]> git.proxmox.com Git - rustc.git/blame - src/librustc/infer/mod.rs
New upstream version 1.12.0+dfsg1
[rustc.git] / src / librustc / infer / mod.rs
CommitLineData
1a4d82fc
JJ
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
85aaf69f 11//! See the Book for more information.
1a4d82fc 12
1a4d82fc
JJ
13pub use self::LateBoundRegionConversionTime::*;
14pub use self::RegionVariableOrigin::*;
15pub use self::SubregionOrigin::*;
1a4d82fc 16pub use self::ValuePairs::*;
54a0048b 17pub use ty::IntVarValue;
1a4d82fc 18pub use self::freshen::TypeFreshener;
e9174d1e 19pub use self::region_inference::{GenericKind, VerifyBound};
1a4d82fc 20
54a0048b
SL
21use hir::def_id::DefId;
22use hir;
bd371182 23use middle::free_region::FreeRegionMap;
c1a9b12d
SL
24use middle::mem_categorization as mc;
25use middle::mem_categorization::McResult;
26use middle::region::CodeExtent;
a7813a04 27use mir::tcx::LvalueTy;
54a0048b
SL
28use ty::subst;
29use ty::subst::Substs;
30use ty::subst::Subst;
31use ty::adjustment;
32use ty::{TyVid, IntVid, FloatVid};
33use ty::{self, Ty, TyCtxt};
34use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
5bcae85e 35use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
54a0048b 36use ty::relate::{Relate, RelateResult, TypeRelation};
5bcae85e 37use traits::{self, PredicateObligations, Reveal};
d9579d0f 38use rustc_data_structures::unify::{self, UnificationTable};
a7813a04 39use std::cell::{Cell, RefCell, Ref, RefMut};
c34b1796 40use std::fmt;
1a4d82fc 41use syntax::ast;
3157f602
XL
42use errors::DiagnosticBuilder;
43use syntax_pos::{self, Span, DUMMY_SP};
e9174d1e 44use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
1a4d82fc 45
c34b1796 46use self::combine::CombineFields;
3157f602 47use self::higher_ranked::HrMatchResult;
1a4d82fc 48use self::region_inference::{RegionVarBindings, RegionSnapshot};
d9579d0f 49use self::unify_key::ToType;
1a4d82fc 50
5bcae85e
SL
51mod bivariate;
52mod combine;
53mod equate;
1a4d82fc 54pub mod error_reporting;
5bcae85e 55mod glb;
1a4d82fc
JJ
56mod higher_ranked;
57pub mod lattice;
5bcae85e 58mod lub;
1a4d82fc
JJ
59pub mod region_inference;
60pub mod resolve;
61mod freshen;
5bcae85e 62mod sub;
1a4d82fc 63pub mod type_variable;
d9579d0f 64pub mod unify_key;
1a4d82fc 65
3157f602 66#[must_use]
54a0048b
SL
67pub struct InferOk<'tcx, T> {
68 pub value: T,
69 pub obligations: PredicateObligations<'tcx>,
70}
71pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
72
1a4d82fc 73pub type Bound<T> = Option<T>;
c34b1796 74pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
c1a9b12d 75pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
1a4d82fc 76
a7813a04
XL
77/// A version of &ty::Tables which can be global or local.
78/// Only the local version supports borrow_mut.
79#[derive(Copy, Clone)]
80pub enum InferTables<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
81 Global(&'a RefCell<ty::Tables<'gcx>>),
82 Local(&'a RefCell<ty::Tables<'tcx>>)
83}
84
85impl<'a, 'gcx, 'tcx> InferTables<'a, 'gcx, 'tcx> {
86 pub fn borrow(self) -> Ref<'a, ty::Tables<'tcx>> {
87 match self {
88 InferTables::Global(tables) => tables.borrow(),
89 InferTables::Local(tables) => tables.borrow()
90 }
91 }
92
93 pub fn borrow_mut(self) -> RefMut<'a, ty::Tables<'tcx>> {
94 match self {
95 InferTables::Global(_) => {
96 bug!("InferTables: infcx.tables.borrow_mut() outside of type-checking");
97 }
98 InferTables::Local(tables) => tables.borrow_mut()
99 }
100 }
101}
102
103pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
104 pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
1a4d82fc 105
a7813a04 106 pub tables: InferTables<'a, 'gcx, 'tcx>,
c1a9b12d 107
3157f602
XL
108 // Cache for projections. This cache is snapshotted along with the
109 // infcx.
110 //
111 // Public so that `traits::project` can use it.
112 pub projection_cache: RefCell<traits::ProjectionCache<'tcx>>,
113
1a4d82fc
JJ
114 // We instantiate UnificationTable with bounds<Ty> because the
115 // types that might instantiate a general type variable have an
116 // order, represented by its upper and lower bounds.
117 type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
118
119 // Map from integral variable to the kind of integer it represents
85aaf69f 120 int_unification_table: RefCell<UnificationTable<ty::IntVid>>,
1a4d82fc
JJ
121
122 // Map from floating variable to the kind of float it represents
85aaf69f 123 float_unification_table: RefCell<UnificationTable<ty::FloatVid>>,
1a4d82fc
JJ
124
125 // For region variables.
a7813a04
XL
126 region_vars: RegionVarBindings<'a, 'gcx, 'tcx>,
127
128 pub parameter_environment: ty::ParameterEnvironment<'gcx>,
129
130 /// Caches the results of trait selection. This cache is used
131 /// for things that have to do with the parameters in scope.
132 pub selection_cache: traits::SelectionCache<'tcx>,
c1a9b12d 133
a7813a04
XL
134 /// Caches the results of trait evaluation.
135 pub evaluation_cache: traits::EvaluationCache<'tcx>,
c1a9b12d 136
e9174d1e
SL
137 // the set of predicates on which errors have been reported, to
138 // avoid reporting the same error twice.
139 pub reported_trait_errors: RefCell<FnvHashSet<traits::TraitErrorKey<'tcx>>>,
140
c1a9b12d
SL
141 // This is a temporary field used for toggling on normalization in the inference context,
142 // as we move towards the approach described here:
143 // https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
144 // At a point sometime in the future normalization will be done by the typing context
145 // directly.
146 normalize: bool,
147
54a0048b
SL
148 // Sadly, the behavior of projection varies a bit depending on the
149 // stage of compilation. The specifics are given in the
5bcae85e
SL
150 // documentation for `Reveal`.
151 projection_mode: Reveal,
54a0048b 152
a7813a04
XL
153 // When an error occurs, we want to avoid reporting "derived"
154 // errors that are due to this original failure. Normally, we
155 // handle this with the `err_count_on_creation` count, which
156 // basically just tracks how many errors were reported when we
157 // started type-checking a fn and checks to see if any new errors
158 // have been reported since then. Not great, but it works.
159 //
160 // However, when errors originated in other passes -- notably
161 // resolve -- this heuristic breaks down. Therefore, we have this
162 // auxiliary flag that one can set whenever one creates a
163 // type-error that is due to an error in a prior pass.
164 //
165 // Don't read this flag directly, call `is_tainted_by_errors()`
166 // and `set_tainted_by_errors()`.
167 tainted_by_errors_flag: Cell<bool>,
168
169 // Track how many errors were reported when this infcx is created.
170 // If the number of errors increases, that's also a sign (line
171 // `tained_by_errors`) to avoid reporting certain kinds of errors.
c1a9b12d 172 err_count_on_creation: usize,
3157f602
XL
173
174 // This flag is used for debugging, and is set to true if there are
175 // any obligations set during the current snapshot. In that case, the
176 // snapshot can't be rolled back.
177 pub obligations_in_snapshot: Cell<bool>,
1a4d82fc
JJ
178}
179
180/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
181/// region that each late-bound region was replaced with.
a7813a04 182pub type SkolemizationMap = FnvHashMap<ty::BoundRegion, ty::Region>;
1a4d82fc
JJ
183
184/// Why did we require that the two types be related?
185///
186/// See `error_reporting.rs` for more details
85aaf69f 187#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
188pub enum TypeOrigin {
189 // Not yet categorized in a better way
190 Misc(Span),
191
192 // Checking that method of impl is compatible with trait
193 MethodCompatCheck(Span),
194
195 // Checking that this expression can be assigned where it needs to be
196 // FIXME(eddyb) #11161 is the original Expr required?
197 ExprAssignable(Span),
198
1a4d82fc
JJ
199 // Relating trait type parameters to those found in impl etc
200 RelateOutputImplTypes(Span),
201
202 // Computing common supertype in the arms of a match expression
92a42be0 203 MatchExpressionArm(Span, Span, hir::MatchSource),
1a4d82fc
JJ
204
205 // Computing common supertype in an if expression
206 IfExpression(Span),
207
208 // Computing common supertype of an if expression with no else counter-part
209 IfExpressionWithNoElse(Span),
210
211 // Computing common supertype in a range expression
212 RangeExpression(Span),
213
214 // `where a == b`
215 EquatePredicate(Span),
5bcae85e
SL
216
217 // `main` has wrong type
218 MainFunctionType(Span),
219
220 // `start` has wrong type
221 StartFunctionType(Span),
222
223 // intrinsic has wrong type
224 IntrinsicType(Span),
225
226 // method receiver
227 MethodReceiver(Span),
1a4d82fc
JJ
228}
229
c34b1796 230impl TypeOrigin {
5bcae85e 231 fn as_failure_str(&self) -> &'static str {
c34b1796
AL
232 match self {
233 &TypeOrigin::Misc(_) |
c34b1796
AL
234 &TypeOrigin::RelateOutputImplTypes(_) |
235 &TypeOrigin::ExprAssignable(_) => "mismatched types",
c34b1796 236 &TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait",
92a42be0
SL
237 &TypeOrigin::MatchExpressionArm(_, _, source) => match source {
238 hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types",
239 _ => "match arms have incompatible types",
240 },
c34b1796
AL
241 &TypeOrigin::IfExpression(_) => "if and else have incompatible types",
242 &TypeOrigin::IfExpressionWithNoElse(_) => "if may be missing an else clause",
243 &TypeOrigin::RangeExpression(_) => "start and end of range have incompatible types",
244 &TypeOrigin::EquatePredicate(_) => "equality predicate not satisfied",
5bcae85e
SL
245 &TypeOrigin::MainFunctionType(_) => "main function has wrong type",
246 &TypeOrigin::StartFunctionType(_) => "start function has wrong type",
247 &TypeOrigin::IntrinsicType(_) => "intrinsic has wrong type",
248 &TypeOrigin::MethodReceiver(_) => "mismatched method receiver",
c34b1796
AL
249 }
250 }
c34b1796 251
5bcae85e
SL
252 fn as_requirement_str(&self) -> &'static str {
253 match self {
254 &TypeOrigin::Misc(_) => "types are compatible",
255 &TypeOrigin::MethodCompatCheck(_) => "method type is compatible with trait",
256 &TypeOrigin::ExprAssignable(_) => "expression is assignable",
257 &TypeOrigin::RelateOutputImplTypes(_) => {
258 "trait type parameters matches those specified on the impl"
259 }
260 &TypeOrigin::MatchExpressionArm(_, _, _) => "match arms have compatible types",
261 &TypeOrigin::IfExpression(_) => "if and else have compatible types",
262 &TypeOrigin::IfExpressionWithNoElse(_) => "if missing an else returns ()",
263 &TypeOrigin::RangeExpression(_) => "start and end of range have compatible types",
264 &TypeOrigin::EquatePredicate(_) => "equality where clause is satisfied",
265 &TypeOrigin::MainFunctionType(_) => "`main` function has the correct type",
266 &TypeOrigin::StartFunctionType(_) => "`start` function has the correct type",
267 &TypeOrigin::IntrinsicType(_) => "intrinsic has the correct type",
268 &TypeOrigin::MethodReceiver(_) => "method receiver has the correct type",
269 }
c34b1796
AL
270 }
271}
272
1a4d82fc 273/// See `error_reporting.rs` for more details
85aaf69f 274#[derive(Clone, Debug)]
1a4d82fc 275pub enum ValuePairs<'tcx> {
e9174d1e
SL
276 Types(ExpectedFound<Ty<'tcx>>),
277 TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
278 PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
1a4d82fc
JJ
279}
280
281/// The trace designates the path through inference that we took to
282/// encounter an error or subtyping constraint.
283///
284/// See `error_reporting.rs` for more details.
62682a34 285#[derive(Clone)]
1a4d82fc
JJ
286pub struct TypeTrace<'tcx> {
287 origin: TypeOrigin,
288 values: ValuePairs<'tcx>,
289}
290
291/// The origin of a `r1 <= r2` constraint.
292///
293/// See `error_reporting.rs` for more details
85aaf69f 294#[derive(Clone, Debug)]
1a4d82fc
JJ
295pub enum SubregionOrigin<'tcx> {
296 // Arose from a subtyping relation
297 Subtype(TypeTrace<'tcx>),
298
299 // Stack-allocated closures cannot outlive innermost loop
300 // or function so as to ensure we only require finite stack
301 InfStackClosure(Span),
302
303 // Invocation of closure must be within its lifetime
304 InvokeClosure(Span),
305
306 // Dereference of reference must be within its lifetime
307 DerefPointer(Span),
308
309 // Closure bound must not outlive captured free variables
310 FreeVariable(Span, ast::NodeId),
311
312 // Index into slice must be within its lifetime
313 IndexSlice(Span),
314
315 // When casting `&'a T` to an `&'b Trait` object,
316 // relating `'a` to `'b`
317 RelateObjectBound(Span),
318
319 // Some type parameter was instantiated with the given type,
320 // and that type must outlive some region.
321 RelateParamBound(Span, Ty<'tcx>),
322
323 // The given region parameter was instantiated with a region
324 // that must outlive some other region.
325 RelateRegionParamBound(Span),
326
327 // A bound placed on type parameters that states that must outlive
328 // the moment of their instantiation.
329 RelateDefaultParamBound(Span, Ty<'tcx>),
330
331 // Creating a pointer `b` to contents of another reference
332 Reborrow(Span),
333
334 // Creating a pointer `b` to contents of an upvar
335 ReborrowUpvar(Span, ty::UpvarId),
336
e9174d1e
SL
337 // Data with type `Ty<'tcx>` was borrowed
338 DataBorrowed(Ty<'tcx>, Span),
339
1a4d82fc
JJ
340 // (&'a &'b T) where a >= b
341 ReferenceOutlivesReferent(Ty<'tcx>, Span),
342
e9174d1e
SL
343 // Type or region parameters must be in scope.
344 ParameterInScope(ParameterOrigin, Span),
345
1a4d82fc
JJ
346 // The type T of an expression E must outlive the lifetime for E.
347 ExprTypeIsNotInScope(Ty<'tcx>, Span),
348
349 // A `ref b` whose region does not enclose the decl site
350 BindingTypeIsNotValidAtDecl(Span),
351
352 // Regions appearing in a method receiver must outlive method call
353 CallRcvr(Span),
354
355 // Regions appearing in a function argument must outlive func call
356 CallArg(Span),
357
358 // Region in return type of invoked fn must enclose call
359 CallReturn(Span),
360
85aaf69f
SL
361 // Operands must be in scope
362 Operand(Span),
363
1a4d82fc
JJ
364 // Region resulting from a `&` expr must enclose the `&` expr
365 AddrOf(Span),
366
367 // An auto-borrow that does not enclose the expr where it occurs
368 AutoBorrow(Span),
85aaf69f
SL
369
370 // Region constraint arriving from destructor safety
371 SafeDestructor(Span),
1a4d82fc
JJ
372}
373
e9174d1e
SL
374/// Places that type/region parameters can appear.
375#[derive(Clone, Copy, Debug)]
376pub enum ParameterOrigin {
377 Path, // foo::bar
378 MethodCall, // foo.bar() <-- parameters on impl providing bar()
379 OverloadedOperator, // a + b when overloaded
380 OverloadedDeref, // *a when overloaded
381}
382
1a4d82fc 383/// Times when we replace late-bound regions with variables:
85aaf69f 384#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
385pub enum LateBoundRegionConversionTime {
386 /// when a fn is called
387 FnCall,
388
389 /// when two higher-ranked types are compared
390 HigherRankedType,
391
392 /// when projecting an associated type
393 AssocTypeProjection(ast::Name),
394}
395
396/// Reasons to create a region inference variable
397///
398/// See `error_reporting.rs` for more details
85aaf69f 399#[derive(Clone, Debug)]
c34b1796 400pub enum RegionVariableOrigin {
1a4d82fc
JJ
401 // Region variables created for ill-categorized reasons,
402 // mostly indicates places in need of refactoring
403 MiscVariable(Span),
404
405 // Regions created by a `&P` or `[...]` pattern
406 PatternRegion(Span),
407
408 // Regions created by `&` operator
409 AddrOfRegion(Span),
410
1a4d82fc
JJ
411 // Regions created as part of an autoref of a method receiver
412 Autoref(Span),
413
414 // Regions created as part of an automatic coercion
c34b1796 415 Coercion(Span),
1a4d82fc
JJ
416
417 // Region variables created as the values for early-bound regions
418 EarlyBoundRegion(Span, ast::Name),
419
420 // Region variables created for bound regions
421 // in a function or method that is called
422 LateBoundRegion(Span, ty::BoundRegion, LateBoundRegionConversionTime),
423
424 UpvarRegion(ty::UpvarId, Span),
425
426 BoundRegionInCoherence(ast::Name),
427}
428
c34b1796 429#[derive(Copy, Clone, Debug)]
c1a9b12d
SL
430pub enum FixupError {
431 UnresolvedIntTy(IntVid),
432 UnresolvedFloatTy(FloatVid),
433 UnresolvedTy(TyVid)
1a4d82fc
JJ
434}
435
a7813a04
XL
436impl fmt::Display for FixupError {
437 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
438 use self::FixupError::*;
1a4d82fc 439
a7813a04
XL
440 match *self {
441 UnresolvedIntTy(_) => {
442 write!(f, "cannot determine the type of this integer; \
443 add a suffix to specify the type explicitly")
444 }
445 UnresolvedFloatTy(_) => {
446 write!(f, "cannot determine the type of this number; \
447 add a suffix to specify the type explicitly")
448 }
449 UnresolvedTy(_) => write!(f, "unconstrained type")
450 }
1a4d82fc
JJ
451 }
452}
453
a7813a04
XL
454/// Helper type of a temporary returned by tcx.infer_ctxt(...).
455/// Necessary because we can't write the following bound:
456/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>).
457pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
458 global_tcx: TyCtxt<'a, 'gcx, 'gcx>,
459 arenas: ty::CtxtArenas<'tcx>,
460 tables: Option<RefCell<ty::Tables<'tcx>>>,
461 param_env: Option<ty::ParameterEnvironment<'gcx>>,
5bcae85e 462 projection_mode: Reveal,
a7813a04 463 normalize: bool
1a4d82fc
JJ
464}
465
a7813a04
XL
466impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
467 pub fn infer_ctxt(self,
468 tables: Option<ty::Tables<'tcx>>,
469 param_env: Option<ty::ParameterEnvironment<'gcx>>,
5bcae85e 470 projection_mode: Reveal)
a7813a04
XL
471 -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
472 InferCtxtBuilder {
473 global_tcx: self,
474 arenas: ty::CtxtArenas::new(),
475 tables: tables.map(RefCell::new),
476 param_env: param_env,
477 projection_mode: projection_mode,
478 normalize: false
479 }
480 }
1a4d82fc 481
5bcae85e 482 pub fn normalizing_infer_ctxt(self, projection_mode: Reveal)
a7813a04
XL
483 -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
484 InferCtxtBuilder {
485 global_tcx: self,
486 arenas: ty::CtxtArenas::new(),
487 tables: None,
488 param_env: None,
489 projection_mode: projection_mode,
490 normalize: false
491 }
492 }
1a4d82fc 493
a7813a04
XL
494 /// Fake InferCtxt with the global tcx. Used by pre-MIR borrowck
495 /// for MemCategorizationContext/ExprUseVisitor.
496 /// If any inference functionality is used, ICEs will occur.
497 pub fn borrowck_fake_infer_ctxt(self, param_env: ty::ParameterEnvironment<'gcx>)
498 -> InferCtxt<'a, 'gcx, 'gcx> {
499 InferCtxt {
500 tcx: self,
501 tables: InferTables::Global(&self.tables),
502 type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
503 int_unification_table: RefCell::new(UnificationTable::new()),
504 float_unification_table: RefCell::new(UnificationTable::new()),
505 region_vars: RegionVarBindings::new(self),
506 parameter_environment: param_env,
507 selection_cache: traits::SelectionCache::new(),
508 evaluation_cache: traits::EvaluationCache::new(),
3157f602 509 projection_cache: RefCell::new(traits::ProjectionCache::new()),
a7813a04
XL
510 reported_trait_errors: RefCell::new(FnvHashSet()),
511 normalize: false,
5bcae85e 512 projection_mode: Reveal::NotSpecializable,
a7813a04 513 tainted_by_errors_flag: Cell::new(false),
3157f602
XL
514 err_count_on_creation: self.sess.err_count(),
515 obligations_in_snapshot: Cell::new(false),
a7813a04
XL
516 }
517 }
92a42be0
SL
518}
519
a7813a04
XL
520impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
521 pub fn enter<F, R>(&'tcx mut self, f: F) -> R
522 where F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R
523 {
524 let InferCtxtBuilder {
525 global_tcx,
526 ref arenas,
527 ref tables,
528 ref mut param_env,
529 projection_mode,
530 normalize
531 } = *self;
532 let tables = if let Some(ref tables) = *tables {
533 InferTables::Local(tables)
534 } else {
535 InferTables::Global(&global_tcx.tables)
536 };
537 let param_env = param_env.take().unwrap_or_else(|| {
538 global_tcx.empty_parameter_environment()
539 });
540 global_tcx.enter_local(arenas, |tcx| f(InferCtxt {
541 tcx: tcx,
542 tables: tables,
3157f602 543 projection_cache: RefCell::new(traits::ProjectionCache::new()),
a7813a04
XL
544 type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
545 int_unification_table: RefCell::new(UnificationTable::new()),
546 float_unification_table: RefCell::new(UnificationTable::new()),
547 region_vars: RegionVarBindings::new(tcx),
548 parameter_environment: param_env,
549 selection_cache: traits::SelectionCache::new(),
550 evaluation_cache: traits::EvaluationCache::new(),
551 reported_trait_errors: RefCell::new(FnvHashSet()),
552 normalize: normalize,
553 projection_mode: projection_mode,
554 tainted_by_errors_flag: Cell::new(false),
3157f602
XL
555 err_count_on_creation: tcx.sess.err_count(),
556 obligations_in_snapshot: Cell::new(false),
a7813a04
XL
557 }))
558 }
54a0048b
SL
559}
560
a7813a04
XL
561impl<T> ExpectedFound<T> {
562 fn new(a_is_expected: bool, a: T, b: T) -> Self {
563 if a_is_expected {
564 ExpectedFound {expected: a, found: b}
565 } else {
566 ExpectedFound {expected: b, found: a}
567 }
54a0048b 568 }
1a4d82fc
JJ
569}
570
a7813a04 571impl<'tcx, T> InferOk<'tcx, T> {
3157f602 572 pub fn unit(self) -> InferOk<'tcx, ()> {
a7813a04 573 InferOk { value: (), obligations: self.obligations }
1a4d82fc
JJ
574 }
575}
576
1a4d82fc
JJ
577#[must_use = "once you start a snapshot, you should always consume it"]
578pub struct CombinedSnapshot {
3157f602 579 projection_cache_snapshot: traits::ProjectionCacheSnapshot,
1a4d82fc
JJ
580 type_snapshot: type_variable::Snapshot,
581 int_snapshot: unify::Snapshot<ty::IntVid>,
582 float_snapshot: unify::Snapshot<ty::FloatVid>,
583 region_vars_snapshot: RegionSnapshot,
3157f602 584 obligations_in_snapshot: bool,
1a4d82fc
JJ
585}
586
a7813a04
XL
587/// Helper trait for shortening the lifetimes inside a
588/// value for post-type-checking normalization.
589pub trait TransNormalize<'gcx>: TypeFoldable<'gcx> {
590 fn trans_normalize<'a, 'tcx>(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>) -> Self;
591}
c1a9b12d 592
a7813a04
XL
593macro_rules! items { ($($item:item)+) => ($($item)+) }
594macro_rules! impl_trans_normalize {
595 ($lt_gcx:tt, $($ty:ty),+) => {
596 items!($(impl<$lt_gcx> TransNormalize<$lt_gcx> for $ty {
597 fn trans_normalize<'a, 'tcx>(&self,
598 infcx: &InferCtxt<'a, $lt_gcx, 'tcx>)
599 -> Self {
600 infcx.normalize_projections_in(self)
601 }
602 })+);
603 }
604}
c1a9b12d 605
a7813a04
XL
606impl_trans_normalize!('gcx,
607 Ty<'gcx>,
608 &'gcx Substs<'gcx>,
609 ty::FnSig<'gcx>,
a7813a04
XL
610 &'gcx ty::BareFnTy<'gcx>,
611 ty::ClosureSubsts<'gcx>,
612 ty::PolyTraitRef<'gcx>
613);
614
615impl<'gcx> TransNormalize<'gcx> for LvalueTy<'gcx> {
616 fn trans_normalize<'a, 'tcx>(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>) -> Self {
617 match *self {
618 LvalueTy::Ty { ty } => LvalueTy::Ty { ty: ty.trans_normalize(infcx) },
619 LvalueTy::Downcast { adt_def, substs, variant_index } => {
620 LvalueTy::Downcast {
621 adt_def: adt_def,
622 substs: substs.trans_normalize(infcx),
623 variant_index: variant_index
624 }
625 }
626 }
c1a9b12d 627 }
a7813a04 628}
c1a9b12d 629
a7813a04
XL
630// NOTE: Callable from trans only!
631impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
632 pub fn normalize_associated_type<T>(self, value: &T) -> T
633 where T: TransNormalize<'tcx>
634 {
635 debug!("normalize_associated_type(t={:?})", value);
c1a9b12d 636
a7813a04 637 let value = self.erase_regions(value);
c1a9b12d 638
a7813a04
XL
639 if !value.has_projection_types() {
640 return value;
641 }
c1a9b12d 642
5bcae85e 643 self.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
a7813a04
XL
644 value.trans_normalize(&infcx)
645 })
c1a9b12d 646 }
3157f602
XL
647
648 pub fn normalize_associated_type_in_env<T>(
649 self, value: &T, env: &'a ty::ParameterEnvironment<'tcx>
650 ) -> T
651 where T: TransNormalize<'tcx>
652 {
653 debug!("normalize_associated_type_in_env(t={:?})", value);
654
655 let value = self.erase_regions(value);
656
657 if !value.has_projection_types() {
658 return value;
659 }
660
5bcae85e 661 self.infer_ctxt(None, Some(env.clone()), Reveal::All).enter(|infcx| {
3157f602
XL
662 value.trans_normalize(&infcx)
663 })
664 }
c1a9b12d
SL
665}
666
a7813a04
XL
667impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
668 fn normalize_projections_in<T>(&self, value: &T) -> T::Lifted
669 where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
670 {
671 let mut selcx = traits::SelectionContext::new(self);
672 let cause = traits::ObligationCause::dummy();
673 let traits::Normalized { value: result, obligations } =
674 traits::normalize(&mut selcx, cause, value);
675
676 debug!("normalize_projections_in: result={:?} obligations={:?}",
677 result, obligations);
678
679 let mut fulfill_cx = traits::FulfillmentContext::new();
680
681 for obligation in obligations {
682 fulfill_cx.register_predicate_obligation(self, obligation);
c1a9b12d 683 }
a7813a04
XL
684
685 self.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result)
c1a9b12d 686 }
c1a9b12d 687
a7813a04
XL
688 pub fn drain_fulfillment_cx_or_panic<T>(&self,
689 span: Span,
690 fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
691 result: &T)
692 -> T::Lifted
693 where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
694 {
3157f602
XL
695 debug!("drain_fulfillment_cx_or_panic()");
696
a7813a04
XL
697 let when = "resolving bounds after type-checking";
698 let v = match self.drain_fulfillment_cx(fulfill_cx, result) {
699 Ok(v) => v,
700 Err(errors) => {
701 span_bug!(span, "Encountered errors `{:?}` {}", errors, when);
702 }
703 };
704
705 match self.tcx.lift_to_global(&v) {
706 Some(v) => v,
707 None => {
708 span_bug!(span, "Uninferred types/regions in `{:?}` {}", v, when);
709 }
c1a9b12d
SL
710 }
711 }
712
a7813a04
XL
713 /// Finishes processes any obligations that remain in the fulfillment
714 /// context, and then "freshens" and returns `result`. This is
715 /// primarily used during normalization and other cases where
716 /// processing the obligations in `fulfill_cx` may cause type
717 /// inference variables that appear in `result` to be unified, and
718 /// hence we need to process those obligations to get the complete
719 /// picture of the type.
720 pub fn drain_fulfillment_cx<T>(&self,
721 fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
722 result: &T)
723 -> Result<T,Vec<traits::FulfillmentError<'tcx>>>
724 where T : TypeFoldable<'tcx>
725 {
726 debug!("drain_fulfillment_cx(result={:?})",
727 result);
c1a9b12d 728
a7813a04
XL
729 // In principle, we only need to do this so long as `result`
730 // contains unbound type parameters. It could be a slight
731 // optimization to stop iterating early.
732 fulfill_cx.select_all_or_error(self)?;
733
734 let result = self.resolve_type_vars_if_possible(result);
735 Ok(self.tcx.erase_regions(&result))
54a0048b 736 }
54a0048b 737
5bcae85e 738 pub fn projection_mode(&self) -> Reveal {
54a0048b
SL
739 self.projection_mode
740 }
741
1a4d82fc
JJ
742 pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
743 t.fold_with(&mut self.freshener())
744 }
745
746 pub fn type_var_diverges(&'a self, ty: Ty) -> bool {
747 match ty.sty {
62682a34 748 ty::TyInfer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
1a4d82fc
JJ
749 _ => false
750 }
751 }
752
a7813a04 753 pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'gcx, 'tcx> {
1a4d82fc
JJ
754 freshen::TypeFreshener::new(self)
755 }
756
757 pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
54a0048b
SL
758 use ty::error::UnconstrainedNumeric::Neither;
759 use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1a4d82fc 760 match ty.sty {
62682a34 761 ty::TyInfer(ty::IntVar(vid)) => {
c34b1796
AL
762 if self.int_unification_table.borrow_mut().has_value(vid) {
763 Neither
764 } else {
765 UnconstrainedInt
1a4d82fc
JJ
766 }
767 },
62682a34 768 ty::TyInfer(ty::FloatVar(vid)) => {
c34b1796
AL
769 if self.float_unification_table.borrow_mut().has_value(vid) {
770 Neither
771 } else {
772 UnconstrainedFloat
1a4d82fc
JJ
773 }
774 },
775 _ => Neither,
776 }
777 }
778
c1a9b12d
SL
779 /// Returns a type variable's default fallback if any exists. A default
780 /// must be attached to the variable when created, if it is created
781 /// without a default, this will return None.
782 ///
783 /// This code does not apply to integral or floating point variables,
784 /// only to use declared defaults.
785 ///
786 /// See `new_ty_var_with_default` to create a type variable with a default.
787 /// See `type_variable::Default` for details about what a default entails.
788 pub fn default(&self, ty: Ty<'tcx>) -> Option<type_variable::Default<'tcx>> {
789 match ty.sty {
790 ty::TyInfer(ty::TyVar(vid)) => self.type_variables.borrow().default(vid),
791 _ => None
792 }
793 }
794
795 pub fn unsolved_variables(&self) -> Vec<ty::Ty<'tcx>> {
796 let mut variables = Vec::new();
797
798 let unbound_ty_vars = self.type_variables
54a0048b 799 .borrow_mut()
c1a9b12d
SL
800 .unsolved_variables()
801 .into_iter()
802 .map(|t| self.tcx.mk_var(t));
803
804 let unbound_int_vars = self.int_unification_table
805 .borrow_mut()
806 .unsolved_variables()
807 .into_iter()
808 .map(|v| self.tcx.mk_int_var(v));
809
810 let unbound_float_vars = self.float_unification_table
811 .borrow_mut()
812 .unsolved_variables()
813 .into_iter()
814 .map(|v| self.tcx.mk_float_var(v));
815
816 variables.extend(unbound_ty_vars);
817 variables.extend(unbound_int_vars);
818 variables.extend(unbound_float_vars);
819
820 return variables;
821 }
822
5bcae85e 823 fn combine_fields(&'a self, trace: TypeTrace<'tcx>)
a7813a04 824 -> CombineFields<'a, 'gcx, 'tcx> {
54a0048b
SL
825 CombineFields {
826 infcx: self,
54a0048b
SL
827 trace: trace,
828 cause: None,
829 obligations: PredicateObligations::new(),
830 }
1a4d82fc
JJ
831 }
832
54a0048b
SL
833 pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
834 -> InferResult<'tcx, T>
a7813a04 835 where T: Relate<'tcx>
c34b1796 836 {
5bcae85e
SL
837 let mut fields = self.combine_fields(trace);
838 let result = fields.equate(a_is_expected).relate(a, b);
839 result.map(move |t| InferOk { value: t, obligations: fields.obligations })
c34b1796
AL
840 }
841
54a0048b
SL
842 pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
843 -> InferResult<'tcx, T>
a7813a04 844 where T: Relate<'tcx>
c34b1796 845 {
5bcae85e
SL
846 let mut fields = self.combine_fields(trace);
847 let result = fields.sub(a_is_expected).relate(a, b);
848 result.map(move |t| InferOk { value: t, obligations: fields.obligations })
1a4d82fc
JJ
849 }
850
54a0048b
SL
851 pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
852 -> InferResult<'tcx, T>
a7813a04 853 where T: Relate<'tcx>
c34b1796 854 {
5bcae85e
SL
855 let mut fields = self.combine_fields(trace);
856 let result = fields.lub(a_is_expected).relate(a, b);
857 result.map(move |t| InferOk { value: t, obligations: fields.obligations })
1a4d82fc
JJ
858 }
859
54a0048b
SL
860 pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
861 -> InferResult<'tcx, T>
a7813a04 862 where T: Relate<'tcx>
c34b1796 863 {
5bcae85e
SL
864 let mut fields = self.combine_fields(trace);
865 let result = fields.glb(a_is_expected).relate(a, b);
866 result.map(move |t| InferOk { value: t, obligations: fields.obligations })
1a4d82fc
JJ
867 }
868
869 fn start_snapshot(&self) -> CombinedSnapshot {
3157f602
XL
870 debug!("start_snapshot()");
871
872 let obligations_in_snapshot = self.obligations_in_snapshot.get();
873 self.obligations_in_snapshot.set(false);
874
1a4d82fc 875 CombinedSnapshot {
3157f602 876 projection_cache_snapshot: self.projection_cache.borrow_mut().snapshot(),
1a4d82fc
JJ
877 type_snapshot: self.type_variables.borrow_mut().snapshot(),
878 int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
879 float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
880 region_vars_snapshot: self.region_vars.start_snapshot(),
3157f602 881 obligations_in_snapshot: obligations_in_snapshot,
1a4d82fc
JJ
882 }
883 }
884
c1a9b12d
SL
885 fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot) {
886 debug!("rollback_to(cause={})", cause);
3157f602
XL
887 let CombinedSnapshot { projection_cache_snapshot,
888 type_snapshot,
1a4d82fc
JJ
889 int_snapshot,
890 float_snapshot,
3157f602
XL
891 region_vars_snapshot,
892 obligations_in_snapshot } = snapshot;
1a4d82fc 893
3157f602
XL
894 assert!(!self.obligations_in_snapshot.get());
895 self.obligations_in_snapshot.set(obligations_in_snapshot);
896
897 self.projection_cache
898 .borrow_mut()
899 .rollback_to(projection_cache_snapshot);
1a4d82fc
JJ
900 self.type_variables
901 .borrow_mut()
902 .rollback_to(type_snapshot);
903 self.int_unification_table
904 .borrow_mut()
905 .rollback_to(int_snapshot);
906 self.float_unification_table
907 .borrow_mut()
908 .rollback_to(float_snapshot);
909 self.region_vars
910 .rollback_to(region_vars_snapshot);
911 }
912
913 fn commit_from(&self, snapshot: CombinedSnapshot) {
3157f602
XL
914 debug!("commit_from()");
915 let CombinedSnapshot { projection_cache_snapshot,
916 type_snapshot,
1a4d82fc
JJ
917 int_snapshot,
918 float_snapshot,
3157f602
XL
919 region_vars_snapshot,
920 obligations_in_snapshot } = snapshot;
921
922 self.obligations_in_snapshot.set(obligations_in_snapshot);
1a4d82fc 923
3157f602
XL
924 self.projection_cache
925 .borrow_mut()
926 .commit(projection_cache_snapshot);
1a4d82fc
JJ
927 self.type_variables
928 .borrow_mut()
929 .commit(type_snapshot);
930 self.int_unification_table
931 .borrow_mut()
932 .commit(int_snapshot);
933 self.float_unification_table
934 .borrow_mut()
935 .commit(float_snapshot);
936 self.region_vars
937 .commit(region_vars_snapshot);
938 }
939
940 /// Execute `f` and commit the bindings
941 pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
942 F: FnOnce() -> R,
943 {
944 debug!("commit()");
945 let snapshot = self.start_snapshot();
946 let r = f();
947 self.commit_from(snapshot);
948 r
949 }
950
c34b1796 951 /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`
1a4d82fc 952 pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
c34b1796 953 F: FnOnce(&CombinedSnapshot) -> Result<T, E>
1a4d82fc 954 {
c34b1796
AL
955 debug!("commit_if_ok()");
956 let snapshot = self.start_snapshot();
957 let r = f(&snapshot);
958 debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
959 match r {
960 Ok(_) => { self.commit_from(snapshot); }
c1a9b12d 961 Err(_) => { self.rollback_to("commit_if_ok -- error", snapshot); }
c34b1796
AL
962 }
963 r
1a4d82fc
JJ
964 }
965
a7813a04
XL
966 // Execute `f` in a snapshot, and commit the bindings it creates
967 pub fn in_snapshot<T, F>(&self, f: F) -> T where
968 F: FnOnce(&CombinedSnapshot) -> T
969 {
970 debug!("in_snapshot()");
971 let snapshot = self.start_snapshot();
972 let r = f(&snapshot);
973 self.commit_from(snapshot);
974 r
975 }
976
85aaf69f
SL
977 /// Execute `f` and commit only the region bindings if successful.
978 /// The function f must be very careful not to leak any non-region
979 /// variables that get created.
980 pub fn commit_regions_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
981 F: FnOnce() -> Result<T, E>
982 {
983 debug!("commit_regions_if_ok()");
3157f602
XL
984 let CombinedSnapshot { projection_cache_snapshot,
985 type_snapshot,
85aaf69f
SL
986 int_snapshot,
987 float_snapshot,
3157f602
XL
988 region_vars_snapshot,
989 obligations_in_snapshot } = self.start_snapshot();
85aaf69f 990
c34b1796 991 let r = self.commit_if_ok(|_| f());
85aaf69f 992
c1a9b12d
SL
993 debug!("commit_regions_if_ok: rolling back everything but regions");
994
3157f602
XL
995 assert!(!self.obligations_in_snapshot.get());
996 self.obligations_in_snapshot.set(obligations_in_snapshot);
997
85aaf69f
SL
998 // Roll back any non-region bindings - they should be resolved
999 // inside `f`, with, e.g. `resolve_type_vars_if_possible`.
3157f602
XL
1000 self.projection_cache
1001 .borrow_mut()
1002 .rollback_to(projection_cache_snapshot);
85aaf69f
SL
1003 self.type_variables
1004 .borrow_mut()
1005 .rollback_to(type_snapshot);
1006 self.int_unification_table
1007 .borrow_mut()
1008 .rollback_to(int_snapshot);
1009 self.float_unification_table
1010 .borrow_mut()
1011 .rollback_to(float_snapshot);
1012
1013 // Commit region vars that may escape through resolved types.
1014 self.region_vars
1015 .commit(region_vars_snapshot);
1016
1017 r
1018 }
1019
1a4d82fc
JJ
1020 /// Execute `f` then unroll any bindings it creates
1021 pub fn probe<R, F>(&self, f: F) -> R where
1022 F: FnOnce(&CombinedSnapshot) -> R,
1023 {
1024 debug!("probe()");
1025 let snapshot = self.start_snapshot();
1026 let r = f(&snapshot);
c1a9b12d 1027 self.rollback_to("probe", snapshot);
1a4d82fc
JJ
1028 r
1029 }
1030
1031 pub fn add_given(&self,
1032 sub: ty::FreeRegion,
1033 sup: ty::RegionVid)
1034 {
1035 self.region_vars.add_given(sub, sup);
1036 }
1037
1038 pub fn sub_types(&self,
1039 a_is_expected: bool,
1040 origin: TypeOrigin,
1041 a: Ty<'tcx>,
1042 b: Ty<'tcx>)
54a0048b 1043 -> InferResult<'tcx, ()>
1a4d82fc 1044 {
62682a34 1045 debug!("sub_types({:?} <: {:?})", a, b);
c34b1796 1046 self.commit_if_ok(|_| {
85aaf69f 1047 let trace = TypeTrace::types(origin, a_is_expected, a, b);
54a0048b 1048 self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
1a4d82fc
JJ
1049 })
1050 }
1051
a7813a04
XL
1052 pub fn can_sub_types(&self,
1053 a: Ty<'tcx>,
1054 b: Ty<'tcx>)
1055 -> UnitResult<'tcx>
1056 {
1057 self.probe(|_| {
3157f602 1058 let origin = TypeOrigin::Misc(syntax_pos::DUMMY_SP);
a7813a04
XL
1059 let trace = TypeTrace::types(origin, true, a, b);
1060 self.sub(true, trace, &a, &b).map(|_| ())
1061 })
1062 }
1063
1a4d82fc
JJ
1064 pub fn eq_types(&self,
1065 a_is_expected: bool,
1066 origin: TypeOrigin,
1067 a: Ty<'tcx>,
1068 b: Ty<'tcx>)
54a0048b 1069 -> InferResult<'tcx, ()>
1a4d82fc 1070 {
c34b1796 1071 self.commit_if_ok(|_| {
85aaf69f 1072 let trace = TypeTrace::types(origin, a_is_expected, a, b);
54a0048b 1073 self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
1a4d82fc
JJ
1074 })
1075 }
1076
92a42be0 1077 pub fn eq_trait_refs(&self,
1a4d82fc
JJ
1078 a_is_expected: bool,
1079 origin: TypeOrigin,
d9579d0f
AL
1080 a: ty::TraitRef<'tcx>,
1081 b: ty::TraitRef<'tcx>)
54a0048b 1082 -> InferResult<'tcx, ()>
1a4d82fc 1083 {
a7813a04 1084 debug!("eq_trait_refs({:?} = {:?})", a, b);
c34b1796 1085 self.commit_if_ok(|_| {
1a4d82fc
JJ
1086 let trace = TypeTrace {
1087 origin: origin,
a7813a04 1088 values: TraitRefs(ExpectedFound::new(a_is_expected, a, b))
1a4d82fc 1089 };
54a0048b 1090 self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
1a4d82fc
JJ
1091 })
1092 }
1093
a7813a04
XL
1094 pub fn eq_impl_headers(&self,
1095 a_is_expected: bool,
1096 origin: TypeOrigin,
1097 a: &ty::ImplHeader<'tcx>,
1098 b: &ty::ImplHeader<'tcx>)
1099 -> InferResult<'tcx, ()>
1100 {
1101 debug!("eq_impl_header({:?} = {:?})", a, b);
1102 match (a.trait_ref, b.trait_ref) {
1103 (Some(a_ref), Some(b_ref)) => self.eq_trait_refs(a_is_expected, origin, a_ref, b_ref),
1104 (None, None) => self.eq_types(a_is_expected, origin, a.self_ty, b.self_ty),
1105 _ => bug!("mk_eq_impl_headers given mismatched impl kinds"),
1106 }
1107 }
1108
1a4d82fc
JJ
1109 pub fn sub_poly_trait_refs(&self,
1110 a_is_expected: bool,
1111 origin: TypeOrigin,
1112 a: ty::PolyTraitRef<'tcx>,
1113 b: ty::PolyTraitRef<'tcx>)
54a0048b 1114 -> InferResult<'tcx, ()>
1a4d82fc 1115 {
a7813a04 1116 debug!("sub_poly_trait_refs({:?} <: {:?})", a, b);
c34b1796 1117 self.commit_if_ok(|_| {
1a4d82fc
JJ
1118 let trace = TypeTrace {
1119 origin: origin,
a7813a04 1120 values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b))
1a4d82fc 1121 };
54a0048b 1122 self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
1a4d82fc
JJ
1123 })
1124 }
1125
a7813a04
XL
1126 pub fn sub_regions(&self,
1127 origin: SubregionOrigin<'tcx>,
1128 a: ty::Region,
1129 b: ty::Region) {
1130 debug!("sub_regions({:?} <: {:?})", a, b);
1131 self.region_vars.make_subregion(origin, a, b);
1a4d82fc
JJ
1132 }
1133
1134 pub fn equality_predicate(&self,
1135 span: Span,
1136 predicate: &ty::PolyEquatePredicate<'tcx>)
54a0048b
SL
1137 -> InferResult<'tcx, ()>
1138 {
c34b1796 1139 self.commit_if_ok(|snapshot| {
1a4d82fc
JJ
1140 let (ty::EquatePredicate(a, b), skol_map) =
1141 self.skolemize_late_bound_regions(predicate, snapshot);
92a42be0 1142 let origin = TypeOrigin::EquatePredicate(span);
a7813a04 1143 let eqty_ok = self.eq_types(false, origin, a, b)?;
3157f602
XL
1144 self.leak_check(false, span, &skol_map, snapshot)?;
1145 self.pop_skolemized(skol_map, snapshot);
1146 Ok(eqty_ok.unit())
1a4d82fc
JJ
1147 })
1148 }
1149
1150 pub fn region_outlives_predicate(&self,
1151 span: Span,
1152 predicate: &ty::PolyRegionOutlivesPredicate)
54a0048b
SL
1153 -> UnitResult<'tcx>
1154 {
c34b1796 1155 self.commit_if_ok(|snapshot| {
1a4d82fc
JJ
1156 let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
1157 self.skolemize_late_bound_regions(predicate, snapshot);
1158 let origin = RelateRegionParamBound(span);
a7813a04 1159 self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
3157f602
XL
1160 self.leak_check(false, span, &skol_map, snapshot)?;
1161 Ok(self.pop_skolemized(skol_map, snapshot))
1a4d82fc
JJ
1162 })
1163 }
1164
1165 pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
1166 self.type_variables
1167 .borrow_mut()
c1a9b12d 1168 .new_var(diverging, None)
1a4d82fc
JJ
1169 }
1170
1171 pub fn next_ty_var(&self) -> Ty<'tcx> {
c1a9b12d
SL
1172 self.tcx.mk_var(self.next_ty_var_id(false))
1173 }
1174
1175 pub fn next_ty_var_with_default(&self,
1176 default: Option<type_variable::Default<'tcx>>) -> Ty<'tcx> {
1177 let ty_var_id = self.type_variables
1178 .borrow_mut()
1179 .new_var(false, default);
1180
1181 self.tcx.mk_var(ty_var_id)
1a4d82fc
JJ
1182 }
1183
1184 pub fn next_diverging_ty_var(&self) -> Ty<'tcx> {
c1a9b12d 1185 self.tcx.mk_var(self.next_ty_var_id(true))
1a4d82fc
JJ
1186 }
1187
c34b1796 1188 pub fn next_ty_vars(&self, n: usize) -> Vec<Ty<'tcx>> {
85aaf69f 1189 (0..n).map(|_i| self.next_ty_var()).collect()
1a4d82fc
JJ
1190 }
1191
1192 pub fn next_int_var_id(&self) -> IntVid {
1193 self.int_unification_table
1194 .borrow_mut()
1195 .new_key(None)
1196 }
1197
1198 pub fn next_float_var_id(&self) -> FloatVid {
1199 self.float_unification_table
1200 .borrow_mut()
1201 .new_key(None)
1202 }
1203
c34b1796 1204 pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
e9174d1e 1205 ty::ReVar(self.region_vars.new_region_var(origin))
1a4d82fc
JJ
1206 }
1207
1208 pub fn region_vars_for_defs(&self,
1209 span: Span,
1210 defs: &[ty::RegionParameterDef])
1211 -> Vec<ty::Region> {
1212 defs.iter()
1213 .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
1214 .collect()
1215 }
1216
c1a9b12d
SL
1217 // We have to take `&mut Substs` in order to provide the correct substitutions for defaults
1218 // along the way, for this reason we don't return them.
1219 pub fn type_vars_for_defs(&self,
1220 span: Span,
1221 space: subst::ParamSpace,
1222 substs: &mut Substs<'tcx>,
1223 defs: &[ty::TypeParameterDef<'tcx>]) {
1224
c1a9b12d
SL
1225 for def in defs.iter() {
1226 let default = def.default.map(|default| {
1227 type_variable::Default {
1228 ty: default.subst_spanned(self.tcx, substs, Some(span)),
1229 origin_span: span,
1230 def_id: def.default_def_id
1231 }
1232 });
1233
1234 let ty_var = self.next_ty_var_with_default(default);
1235 substs.types.push(space, ty_var);
c1a9b12d
SL
1236 }
1237 }
1238
1a4d82fc
JJ
1239 /// Given a set of generics defined on a type or impl, returns a substitution mapping each
1240 /// type/region parameter to a fresh inference variable.
1241 pub fn fresh_substs_for_generics(&self,
1242 span: Span,
1243 generics: &ty::Generics<'tcx>)
a7813a04 1244 -> &'tcx subst::Substs<'tcx>
1a4d82fc 1245 {
c1a9b12d
SL
1246 let type_params = subst::VecPerParamSpace::empty();
1247
1a4d82fc
JJ
1248 let region_params =
1249 generics.regions.map(
1250 |d| self.next_region_var(EarlyBoundRegion(span, d.name)));
c1a9b12d
SL
1251
1252 let mut substs = subst::Substs::new(type_params, region_params);
1253
1254 for space in subst::ParamSpace::all().iter() {
1255 self.type_vars_for_defs(
1256 span,
1257 *space,
1258 &mut substs,
1259 generics.types.get_slice(*space));
1260 }
1261
a7813a04 1262 self.tcx.mk_substs(substs)
1a4d82fc
JJ
1263 }
1264
1265 /// Given a set of generics defined on a trait, returns a substitution mapping each output
1266 /// type/region parameter to a fresh inference variable, and mapping the self type to
1267 /// `self_ty`.
1268 pub fn fresh_substs_for_trait(&self,
1269 span: Span,
1270 generics: &ty::Generics<'tcx>,
1271 self_ty: Ty<'tcx>)
1272 -> subst::Substs<'tcx>
1273 {
1274
1275 assert!(generics.types.len(subst::SelfSpace) == 1);
1276 assert!(generics.types.len(subst::FnSpace) == 0);
1277 assert!(generics.regions.len(subst::SelfSpace) == 0);
1278 assert!(generics.regions.len(subst::FnSpace) == 0);
1279
c1a9b12d 1280 let type_params = Vec::new();
1a4d82fc
JJ
1281
1282 let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
1283 let regions = self.region_vars_for_defs(span, region_param_defs);
1284
c1a9b12d
SL
1285 let mut substs = subst::Substs::new_trait(type_params, regions, self_ty);
1286
1287 let type_parameter_defs = generics.types.get_slice(subst::TypeSpace);
1288 self.type_vars_for_defs(span, subst::TypeSpace, &mut substs, type_parameter_defs);
1289
1290 return substs;
1a4d82fc
JJ
1291 }
1292
1293 pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
1294 self.region_vars.new_bound(debruijn)
1295 }
1296
c1a9b12d
SL
1297 /// Apply `adjustment` to the type of `expr`
1298 pub fn adjust_expr_ty(&self,
e9174d1e
SL
1299 expr: &hir::Expr,
1300 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
c1a9b12d
SL
1301 -> Ty<'tcx>
1302 {
1303 let raw_ty = self.expr_ty(expr);
1304 let raw_ty = self.shallow_resolve(raw_ty);
1305 let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
1306 raw_ty.adjust(self.tcx,
1307 expr.span,
1308 expr.id,
1309 adjustment,
1310 |method_call| self.tables
1311 .borrow()
1312 .method_map
1313 .get(&method_call)
1314 .map(|method| resolve_ty(method.ty)))
1315 }
1316
a7813a04
XL
1317 /// True if errors have been reported since this infcx was
1318 /// created. This is sometimes used as a heuristic to skip
1319 /// reporting errors that often occur as a result of earlier
1320 /// errors, but where it's hard to be 100% sure (e.g., unresolved
1321 /// inference variables, regionck errors).
1322 pub fn is_tainted_by_errors(&self) -> bool {
1323 debug!("is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
1324 tainted_by_errors_flag={})",
1325 self.tcx.sess.err_count(),
1326 self.err_count_on_creation,
1327 self.tainted_by_errors_flag.get());
1328
1329 if self.tcx.sess.err_count() > self.err_count_on_creation {
1330 return true; // errors reported since this infcx was made
1331 }
1332 self.tainted_by_errors_flag.get()
1333 }
1334
1335 /// Set the "tainted by errors" flag to true. We call this when we
1336 /// observe an error from a prior pass.
1337 pub fn set_tainted_by_errors(&self) {
1338 debug!("set_tainted_by_errors()");
1339 self.tainted_by_errors_flag.set(true)
7453a54e
SL
1340 }
1341
c1a9b12d
SL
1342 pub fn node_type(&self, id: ast::NodeId) -> Ty<'tcx> {
1343 match self.tables.borrow().node_types.get(&id) {
1344 Some(&t) => t,
1345 // FIXME
a7813a04 1346 None if self.is_tainted_by_errors() =>
c1a9b12d
SL
1347 self.tcx.types.err,
1348 None => {
54a0048b
SL
1349 bug!("no type for node {}: {} in fcx",
1350 id, self.tcx.map.node_to_string(id));
c1a9b12d
SL
1351 }
1352 }
1353 }
1354
e9174d1e 1355 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
c1a9b12d
SL
1356 match self.tables.borrow().node_types.get(&ex.id) {
1357 Some(&t) => t,
1358 None => {
54a0048b 1359 bug!("no type for expr in fcx");
c1a9b12d
SL
1360 }
1361 }
1362 }
1363
bd371182
AL
1364 pub fn resolve_regions_and_report_errors(&self,
1365 free_regions: &FreeRegionMap,
1366 subject_node_id: ast::NodeId) {
1367 let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
a7813a04 1368 if !self.is_tainted_by_errors() {
7453a54e
SL
1369 // As a heuristic, just skip reporting region errors
1370 // altogether if other errors have been reported while
1371 // this infcx was in use. This is totally hokey but
1372 // otherwise we have a hard time separating legit region
1373 // errors from silly ones.
1374 self.report_region_errors(&errors); // see error_reporting.rs
1375 }
1a4d82fc
JJ
1376 }
1377
1378 pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
62682a34 1379 self.resolve_type_vars_if_possible(&t).to_string()
1a4d82fc
JJ
1380 }
1381
1382 pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
1383 let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
c1a9b12d 1384 format!("({})", tstrs.join(", "))
1a4d82fc
JJ
1385 }
1386
d9579d0f 1387 pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
62682a34 1388 self.resolve_type_vars_if_possible(t).to_string()
1a4d82fc
JJ
1389 }
1390
1391 pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
1392 match typ.sty {
62682a34 1393 ty::TyInfer(ty::TyVar(v)) => {
1a4d82fc
JJ
1394 // Not entirely obvious: if `typ` is a type variable,
1395 // it can be resolved to an int/float variable, which
1396 // can then be recursively resolved, hence the
1397 // recursion. Note though that we prevent type
1398 // variables from unifying to other type variables
1399 // directly (though they may be embedded
1400 // structurally), and we prevent cycles in any case,
1401 // so this recursion should always be of very limited
1402 // depth.
54a0048b 1403 self.type_variables.borrow_mut()
1a4d82fc
JJ
1404 .probe(v)
1405 .map(|t| self.shallow_resolve(t))
1406 .unwrap_or(typ)
1407 }
1408
62682a34 1409 ty::TyInfer(ty::IntVar(v)) => {
c34b1796
AL
1410 self.int_unification_table
1411 .borrow_mut()
1412 .probe(v)
1413 .map(|v| v.to_type(self.tcx))
1a4d82fc
JJ
1414 .unwrap_or(typ)
1415 }
1416
62682a34 1417 ty::TyInfer(ty::FloatVar(v)) => {
c34b1796
AL
1418 self.float_unification_table
1419 .borrow_mut()
1420 .probe(v)
1421 .map(|v| v.to_type(self.tcx))
1a4d82fc
JJ
1422 .unwrap_or(typ)
1423 }
1424
1425 _ => {
1426 typ
1427 }
1428 }
1429 }
1430
e9174d1e 1431 pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
9cc50fc6 1432 where T: TypeFoldable<'tcx>
e9174d1e 1433 {
1a4d82fc
JJ
1434 /*!
1435 * Where possible, replaces type/int/float variables in
1436 * `value` with their final value. Note that region variables
1437 * are unaffected. If a type variable has not been unified, it
1438 * is left as is. This is an idempotent operation that does
1439 * not affect inference state in any way and so you can do it
1440 * at will.
1441 */
1442
e9174d1e
SL
1443 if !value.needs_infer() {
1444 return value.clone(); // avoid duplicated subst-folding
1445 }
1a4d82fc
JJ
1446 let mut r = resolve::OpportunisticTypeResolver::new(self);
1447 value.fold_with(&mut r)
1448 }
1449
9cc50fc6
SL
1450 pub fn resolve_type_and_region_vars_if_possible<T>(&self, value: &T) -> T
1451 where T: TypeFoldable<'tcx>
1452 {
1453 let mut r = resolve::OpportunisticTypeAndRegionResolver::new(self);
1454 value.fold_with(&mut r)
1455 }
1456
c1a9b12d
SL
1457 /// Resolves all type variables in `t` and then, if any were left
1458 /// unresolved, substitutes an error type. This is used after the
1459 /// main checking when doing a second pass before writeback. The
1460 /// justification is that writeback will produce an error for
1461 /// these unconstrained type variables.
1462 fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult<Ty<'tcx>> {
1463 let ty = self.resolve_type_vars_if_possible(t);
1464 if ty.references_error() || ty.is_ty_var() {
1465 debug!("resolve_type_vars_or_error: error from {:?}", ty);
1466 Err(())
1467 } else {
1468 Ok(ty)
1469 }
1470 }
1471
1472 pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {
1a4d82fc
JJ
1473 /*!
1474 * Attempts to resolve all type/region variables in
1475 * `value`. Region inference must have been run already (e.g.,
1476 * by calling `resolve_regions_and_report_errors`). If some
1477 * variable was never unified, an `Err` results.
1478 *
1479 * This method is idempotent, but it not typically not invoked
1480 * except during the writeback phase.
1481 */
1482
1483 resolve::fully_resolve(self, value)
1484 }
1485
1486 // [Note-Type-error-reporting]
62682a34 1487 // An invariant is that anytime the expected or actual type is TyError (the special
1a4d82fc
JJ
1488 // error type, meaning that an error occurred when typechecking this expression),
1489 // this is a derived error. The error cascaded from another error (that was already
1490 // reported), so it's not useful to display it to the user.
5bcae85e 1491 // The following methods implement this logic.
62682a34 1492 // They check if either the actual or expected type is TyError, and don't print the error
1a4d82fc 1493 // in this case. The typechecker should only ever report type errors involving mismatched
5bcae85e 1494 // types using one of these methods, and should not call span_err directly for such
1a4d82fc 1495 // errors.
1a4d82fc
JJ
1496
1497 pub fn type_error_message<M>(&self,
1498 sp: Span,
1499 mk_msg: M,
5bcae85e 1500 actual_ty: Ty<'tcx>)
9cc50fc6
SL
1501 where M: FnOnce(String) -> String,
1502 {
5bcae85e 1503 self.type_error_struct(sp, mk_msg, actual_ty).emit();
9cc50fc6
SL
1504 }
1505
5bcae85e 1506 // FIXME: this results in errors without an error code. Deprecate?
9cc50fc6
SL
1507 pub fn type_error_struct<M>(&self,
1508 sp: Span,
1509 mk_msg: M,
5bcae85e 1510 actual_ty: Ty<'tcx>)
9cc50fc6
SL
1511 -> DiagnosticBuilder<'tcx>
1512 where M: FnOnce(String) -> String,
5bcae85e
SL
1513 {
1514 self.type_error_struct_with_diag(sp, |actual_ty| {
1515 self.tcx.sess.struct_span_err(sp, &mk_msg(actual_ty))
1516 }, actual_ty)
1517 }
1518
1519 pub fn type_error_struct_with_diag<M>(&self,
1520 sp: Span,
1521 mk_diag: M,
1522 actual_ty: Ty<'tcx>)
1523 -> DiagnosticBuilder<'tcx>
1524 where M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
1a4d82fc
JJ
1525 {
1526 let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
5bcae85e 1527 debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
1a4d82fc 1528
62682a34 1529 // Don't report an error if actual type is TyError.
c1a9b12d 1530 if actual_ty.references_error() {
9cc50fc6 1531 return self.tcx.sess.diagnostic().struct_dummy();
1a4d82fc
JJ
1532 }
1533
5bcae85e 1534 mk_diag(self.ty_to_string(actual_ty))
1a4d82fc
JJ
1535 }
1536
1537 pub fn report_mismatched_types(&self,
54a0048b 1538 origin: TypeOrigin,
1a4d82fc
JJ
1539 expected: Ty<'tcx>,
1540 actual: Ty<'tcx>,
54a0048b 1541 err: TypeError<'tcx>) {
1a4d82fc 1542 let trace = TypeTrace {
54a0048b 1543 origin: origin,
e9174d1e 1544 values: Types(ExpectedFound {
1a4d82fc
JJ
1545 expected: expected,
1546 found: actual
1547 })
1548 };
54a0048b 1549 self.report_and_explain_type_error(trace, &err).emit();
1a4d82fc
JJ
1550 }
1551
c1a9b12d
SL
1552 pub fn report_conflicting_default_types(&self,
1553 span: Span,
1554 expected: type_variable::Default<'tcx>,
1555 actual: type_variable::Default<'tcx>) {
1556 let trace = TypeTrace {
92a42be0 1557 origin: TypeOrigin::Misc(span),
e9174d1e 1558 values: Types(ExpectedFound {
c1a9b12d
SL
1559 expected: expected.ty,
1560 found: actual.ty
1561 })
1562 };
1563
54a0048b
SL
1564 self.report_and_explain_type_error(
1565 trace,
e9174d1e 1566 &TypeError::TyParamDefaultMismatch(ExpectedFound {
c1a9b12d
SL
1567 expected: expected,
1568 found: actual
54a0048b
SL
1569 }))
1570 .emit();
c1a9b12d
SL
1571 }
1572
1a4d82fc
JJ
1573 pub fn replace_late_bound_regions_with_fresh_var<T>(
1574 &self,
1575 span: Span,
1576 lbrct: LateBoundRegionConversionTime,
1577 value: &ty::Binder<T>)
1578 -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
62682a34 1579 where T : TypeFoldable<'tcx>
1a4d82fc 1580 {
e9174d1e 1581 self.tcx.replace_late_bound_regions(
1a4d82fc
JJ
1582 value,
1583 |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
1584 }
1585
3157f602
XL
1586 /// Given a higher-ranked projection predicate like:
1587 ///
1588 /// for<'a> <T as Fn<&'a u32>>::Output = &'a u32
1589 ///
1590 /// and a target trait-ref like:
1591 ///
1592 /// <T as Fn<&'x u32>>
1593 ///
1594 /// find a substitution `S` for the higher-ranked regions (here,
1595 /// `['a => 'x]`) such that the predicate matches the trait-ref,
1596 /// and then return the value (here, `&'a u32`) but with the
1597 /// substitution applied (hence, `&'x u32`).
1598 ///
1599 /// See `higher_ranked_match` in `higher_ranked/mod.rs` for more
1600 /// details.
1601 pub fn match_poly_projection_predicate(&self,
1602 origin: TypeOrigin,
1603 match_a: ty::PolyProjectionPredicate<'tcx>,
1604 match_b: ty::TraitRef<'tcx>)
1605 -> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
1606 {
1607 let span = origin.span();
1608 let match_trait_ref = match_a.skip_binder().projection_ty.trait_ref;
1609 let trace = TypeTrace {
1610 origin: origin,
1611 values: TraitRefs(ExpectedFound::new(true, match_trait_ref, match_b))
1612 };
1613
1614 let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref, p.ty));
5bcae85e
SL
1615 let mut combine = self.combine_fields(trace);
1616 let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?;
3157f602
XL
1617 Ok(InferOk { value: result, obligations: combine.obligations })
1618 }
1619
1a4d82fc
JJ
1620 /// See `verify_generic_bound` method in `region_inference`
1621 pub fn verify_generic_bound(&self,
1622 origin: SubregionOrigin<'tcx>,
1623 kind: GenericKind<'tcx>,
1624 a: ty::Region,
e9174d1e 1625 bound: VerifyBound) {
62682a34
SL
1626 debug!("verify_generic_bound({:?}, {:?} <: {:?})",
1627 kind,
1628 a,
e9174d1e 1629 bound);
1a4d82fc 1630
e9174d1e 1631 self.region_vars.verify_generic_bound(origin, kind, a, bound);
1a4d82fc
JJ
1632 }
1633
a7813a04
XL
1634 pub fn can_equate<T>(&self, a: &T, b: &T) -> UnitResult<'tcx>
1635 where T: Relate<'tcx> + fmt::Debug
1a4d82fc 1636 {
62682a34 1637 debug!("can_equate({:?}, {:?})", a, b);
1a4d82fc
JJ
1638 self.probe(|_| {
1639 // Gin up a dummy trace, since this won't be committed
1640 // anyhow. We should make this typetrace stuff more
1641 // generic so we don't have to do anything quite this
1642 // terrible.
a7813a04 1643 self.equate(true, TypeTrace::dummy(self.tcx), a, b)
c34b1796 1644 }).map(|_| ())
1a4d82fc 1645 }
c1a9b12d
SL
1646
1647 pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
1648 let ty = self.node_type(id);
1649 self.resolve_type_vars_or_error(&ty)
1650 }
1651
e9174d1e 1652 pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
c1a9b12d
SL
1653 let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
1654 self.resolve_type_vars_or_error(&ty)
1655 }
1656
1657 pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
1658 let ty = self.resolve_type_vars_if_possible(&ty);
a7813a04
XL
1659 if let Some(ty) = self.tcx.lift_to_global(&ty) {
1660 // Even if the type may have no inference variables, during
1661 // type-checking closure types are in local tables only.
1662 let local_closures = match self.tables {
1663 InferTables::Local(_) => ty.has_closure_types(),
1664 InferTables::Global(_) => false
1665 };
1666 if !local_closures {
1667 return ty.moves_by_default(self.tcx.global_tcx(), self.param_env(), span);
1668 }
e9174d1e 1669 }
a7813a04
XL
1670
1671 // this can get called from typeck (by euv), and moves_by_default
1672 // rightly refuses to work with inference variables, but
1673 // moves_by_default has a cache, which we want to use in other
1674 // cases.
1675 !traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
c1a9b12d
SL
1676 }
1677
1678 pub fn node_method_ty(&self, method_call: ty::MethodCall)
1679 -> Option<Ty<'tcx>> {
1680 self.tables
1681 .borrow()
1682 .method_map
1683 .get(&method_call)
1684 .map(|method| method.ty)
1685 .map(|ty| self.resolve_type_vars_if_possible(&ty))
1686 }
1687
1688 pub fn node_method_id(&self, method_call: ty::MethodCall)
e9174d1e 1689 -> Option<DefId> {
c1a9b12d
SL
1690 self.tables
1691 .borrow()
1692 .method_map
1693 .get(&method_call)
1694 .map(|method| method.def_id)
1695 }
1696
e9174d1e 1697 pub fn adjustments(&self) -> Ref<NodeMap<adjustment::AutoAdjustment<'tcx>>> {
c1a9b12d 1698 fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
e9174d1e 1699 -> &'a NodeMap<adjustment::AutoAdjustment<'tcx>> {
c1a9b12d
SL
1700 &tables.adjustments
1701 }
1702
1703 Ref::map(self.tables.borrow(), project_adjustments)
1704 }
1705
1706 pub fn is_method_call(&self, id: ast::NodeId) -> bool {
1707 self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
1708 }
1709
1710 pub fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
1711 self.tcx.region_maps.temporary_scope(rvalue_id)
1712 }
1713
1714 pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
1715 self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
1716 }
1717
a7813a04 1718 pub fn param_env(&self) -> &ty::ParameterEnvironment<'gcx> {
c1a9b12d
SL
1719 &self.parameter_environment
1720 }
1721
1722 pub fn closure_kind(&self,
e9174d1e 1723 def_id: DefId)
c1a9b12d
SL
1724 -> Option<ty::ClosureKind>
1725 {
b039eaaf
SL
1726 if def_id.is_local() {
1727 self.tables.borrow().closure_kinds.get(&def_id).cloned()
1728 } else {
1729 // During typeck, ALL closures are local. But afterwards,
1730 // during trans, we see closure ids from other traits.
1731 // That may require loading the closure data out of the
1732 // cstore.
a7813a04 1733 Some(self.tcx.closure_kind(def_id))
b039eaaf 1734 }
c1a9b12d
SL
1735 }
1736
1737 pub fn closure_type(&self,
e9174d1e 1738 def_id: DefId,
a7813a04 1739 substs: ty::ClosureSubsts<'tcx>)
c1a9b12d
SL
1740 -> ty::ClosureTy<'tcx>
1741 {
a7813a04
XL
1742 if let InferTables::Local(tables) = self.tables {
1743 if let Some(ty) = tables.borrow().closure_tys.get(&def_id) {
1744 return ty.subst(self.tcx, substs.func_substs);
1745 }
1746 }
c1a9b12d 1747
a7813a04 1748 let closure_ty = self.tcx.closure_type(def_id, substs);
c1a9b12d 1749 if self.normalize {
a7813a04
XL
1750 let closure_ty = self.tcx.erase_regions(&closure_ty);
1751
1752 if !closure_ty.has_projection_types() {
1753 return closure_ty;
1754 }
1755
1756 self.normalize_projections_in(&closure_ty)
c1a9b12d
SL
1757 } else {
1758 closure_ty
1759 }
1760 }
1a4d82fc
JJ
1761}
1762
a7813a04 1763impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
1a4d82fc
JJ
1764 pub fn span(&self) -> Span {
1765 self.origin.span()
1766 }
1767
85aaf69f
SL
1768 pub fn types(origin: TypeOrigin,
1769 a_is_expected: bool,
1770 a: Ty<'tcx>,
1771 b: Ty<'tcx>)
1772 -> TypeTrace<'tcx> {
1773 TypeTrace {
1774 origin: origin,
a7813a04 1775 values: Types(ExpectedFound::new(a_is_expected, a, b))
85aaf69f
SL
1776 }
1777 }
1778
a7813a04 1779 pub fn dummy(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TypeTrace<'tcx> {
1a4d82fc 1780 TypeTrace {
3157f602 1781 origin: TypeOrigin::Misc(syntax_pos::DUMMY_SP),
e9174d1e 1782 values: Types(ExpectedFound {
1a4d82fc
JJ
1783 expected: tcx.types.err,
1784 found: tcx.types.err,
1785 })
1786 }
1787 }
1788}
1789
62682a34
SL
1790impl<'tcx> fmt::Debug for TypeTrace<'tcx> {
1791 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1792 write!(f, "TypeTrace({:?})", self.origin)
1a4d82fc
JJ
1793 }
1794}
1795
1796impl TypeOrigin {
1797 pub fn span(&self) -> Span {
1798 match *self {
92a42be0
SL
1799 TypeOrigin::MethodCompatCheck(span) => span,
1800 TypeOrigin::ExprAssignable(span) => span,
1801 TypeOrigin::Misc(span) => span,
92a42be0
SL
1802 TypeOrigin::RelateOutputImplTypes(span) => span,
1803 TypeOrigin::MatchExpressionArm(match_span, _, _) => match_span,
1804 TypeOrigin::IfExpression(span) => span,
1805 TypeOrigin::IfExpressionWithNoElse(span) => span,
1806 TypeOrigin::RangeExpression(span) => span,
1807 TypeOrigin::EquatePredicate(span) => span,
5bcae85e
SL
1808 TypeOrigin::MainFunctionType(span) => span,
1809 TypeOrigin::StartFunctionType(span) => span,
1810 TypeOrigin::IntrinsicType(span) => span,
1811 TypeOrigin::MethodReceiver(span) => span,
1a4d82fc
JJ
1812 }
1813 }
1814}
1815
1a4d82fc
JJ
1816impl<'tcx> SubregionOrigin<'tcx> {
1817 pub fn span(&self) -> Span {
1818 match *self {
1819 Subtype(ref a) => a.span(),
1820 InfStackClosure(a) => a,
1821 InvokeClosure(a) => a,
1822 DerefPointer(a) => a,
1823 FreeVariable(a, _) => a,
1824 IndexSlice(a) => a,
1825 RelateObjectBound(a) => a,
1826 RelateParamBound(a, _) => a,
1827 RelateRegionParamBound(a) => a,
1828 RelateDefaultParamBound(a, _) => a,
1829 Reborrow(a) => a,
1830 ReborrowUpvar(a, _) => a,
e9174d1e 1831 DataBorrowed(_, a) => a,
1a4d82fc 1832 ReferenceOutlivesReferent(_, a) => a,
e9174d1e 1833 ParameterInScope(_, a) => a,
1a4d82fc
JJ
1834 ExprTypeIsNotInScope(_, a) => a,
1835 BindingTypeIsNotValidAtDecl(a) => a,
1836 CallRcvr(a) => a,
1837 CallArg(a) => a,
1838 CallReturn(a) => a,
85aaf69f 1839 Operand(a) => a,
1a4d82fc
JJ
1840 AddrOf(a) => a,
1841 AutoBorrow(a) => a,
85aaf69f 1842 SafeDestructor(a) => a,
1a4d82fc
JJ
1843 }
1844 }
1845}
1846
c34b1796 1847impl RegionVariableOrigin {
1a4d82fc
JJ
1848 pub fn span(&self) -> Span {
1849 match *self {
1850 MiscVariable(a) => a,
1851 PatternRegion(a) => a,
1852 AddrOfRegion(a) => a,
1a4d82fc 1853 Autoref(a) => a,
c34b1796 1854 Coercion(a) => a,
1a4d82fc
JJ
1855 EarlyBoundRegion(a, _) => a,
1856 LateBoundRegion(a, _, _) => a,
3157f602 1857 BoundRegionInCoherence(_) => syntax_pos::DUMMY_SP,
1a4d82fc
JJ
1858 UpvarRegion(_, a) => a
1859 }
1860 }
1861}
5bcae85e
SL
1862
1863impl<'tcx> TypeFoldable<'tcx> for TypeOrigin {
1864 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
1865 self.clone()
1866 }
1867
1868 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
1869 false
1870 }
1871}
1872
1873impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
1874 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1875 match *self {
1876 ValuePairs::Types(ref ef) => {
1877 ValuePairs::Types(ef.fold_with(folder))
1878 }
1879 ValuePairs::TraitRefs(ref ef) => {
1880 ValuePairs::TraitRefs(ef.fold_with(folder))
1881 }
1882 ValuePairs::PolyTraitRefs(ref ef) => {
1883 ValuePairs::PolyTraitRefs(ef.fold_with(folder))
1884 }
1885 }
1886 }
1887
1888 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1889 match *self {
1890 ValuePairs::Types(ref ef) => ef.visit_with(visitor),
1891 ValuePairs::TraitRefs(ref ef) => ef.visit_with(visitor),
1892 ValuePairs::PolyTraitRefs(ref ef) => ef.visit_with(visitor),
1893 }
1894 }
1895}
1896
1897impl<'tcx> TypeFoldable<'tcx> for TypeTrace<'tcx> {
1898 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1899 TypeTrace {
1900 origin: self.origin.fold_with(folder),
1901 values: self.values.fold_with(folder)
1902 }
1903 }
1904
1905 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1906 self.origin.visit_with(visitor) || self.values.visit_with(visitor)
1907 }
1908}