]> git.proxmox.com Git - rustc.git/blame - src/librustc/middle/infer/mod.rs
Imported Upstream version 1.4.0+dfsg1
[rustc.git] / src / librustc / middle / 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::*;
16pub use self::TypeOrigin::*;
17pub use self::ValuePairs::*;
1a4d82fc
JJ
18pub use middle::ty::IntVarValue;
19pub use self::freshen::TypeFreshener;
e9174d1e 20pub use self::region_inference::{GenericKind, VerifyBound};
1a4d82fc 21
e9174d1e
SL
22use middle::def_id::DefId;
23use rustc_front::hir;
bd371182 24use middle::free_region::FreeRegionMap;
c1a9b12d
SL
25use middle::mem_categorization as mc;
26use middle::mem_categorization::McResult;
27use middle::region::CodeExtent;
1a4d82fc
JJ
28use middle::subst;
29use middle::subst::Substs;
c1a9b12d
SL
30use middle::subst::Subst;
31use middle::traits::{self, FulfillmentContext, Normalized,
32 SelectionContext, ObligationCause};
e9174d1e
SL
33use middle::ty::adjustment;
34use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
35use middle::ty::{self, Ty, HasTypeFlags};
36use middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
37use middle::ty::fold::{TypeFolder, TypeFoldable};
38use middle::ty::relate::{Relate, RelateResult, TypeRelation};
d9579d0f 39use rustc_data_structures::unify::{self, UnificationTable};
c1a9b12d 40use std::cell::{RefCell, Ref};
c34b1796 41use std::fmt;
e9174d1e 42use std::rc::Rc;
1a4d82fc
JJ
43use syntax::ast;
44use syntax::codemap;
c1a9b12d 45use syntax::codemap::{Span, DUMMY_SP};
e9174d1e 46use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
1a4d82fc 47
c34b1796 48use self::combine::CombineFields;
1a4d82fc 49use self::region_inference::{RegionVarBindings, RegionSnapshot};
1a4d82fc 50use self::error_reporting::ErrorReporting;
d9579d0f 51use self::unify_key::ToType;
1a4d82fc 52
85aaf69f 53pub mod bivariate;
1a4d82fc 54pub mod combine;
1a4d82fc
JJ
55pub mod equate;
56pub mod error_reporting;
57pub mod glb;
58mod higher_ranked;
59pub mod lattice;
60pub mod lub;
61pub mod region_inference;
62pub mod resolve;
63mod freshen;
64pub mod sub;
65pub mod type_variable;
d9579d0f 66pub mod unify_key;
1a4d82fc
JJ
67
68pub type Bound<T> = Option<T>;
c34b1796 69pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
c1a9b12d 70pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
1a4d82fc
JJ
71
72pub struct InferCtxt<'a, 'tcx: 'a> {
73 pub tcx: &'a ty::ctxt<'tcx>,
74
c1a9b12d
SL
75 pub tables: &'a RefCell<ty::Tables<'tcx>>,
76
1a4d82fc
JJ
77 // We instantiate UnificationTable with bounds<Ty> because the
78 // types that might instantiate a general type variable have an
79 // order, represented by its upper and lower bounds.
80 type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
81
82 // Map from integral variable to the kind of integer it represents
85aaf69f 83 int_unification_table: RefCell<UnificationTable<ty::IntVid>>,
1a4d82fc
JJ
84
85 // Map from floating variable to the kind of float it represents
85aaf69f 86 float_unification_table: RefCell<UnificationTable<ty::FloatVid>>,
1a4d82fc
JJ
87
88 // For region variables.
85aaf69f 89 region_vars: RegionVarBindings<'a, 'tcx>,
c1a9b12d
SL
90
91 pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
92
93 pub fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
94
e9174d1e
SL
95 // the set of predicates on which errors have been reported, to
96 // avoid reporting the same error twice.
97 pub reported_trait_errors: RefCell<FnvHashSet<traits::TraitErrorKey<'tcx>>>,
98
c1a9b12d
SL
99 // This is a temporary field used for toggling on normalization in the inference context,
100 // as we move towards the approach described here:
101 // https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
102 // At a point sometime in the future normalization will be done by the typing context
103 // directly.
104 normalize: bool,
105
106 err_count_on_creation: usize,
1a4d82fc
JJ
107}
108
109/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
110/// region that each late-bound region was replaced with.
111pub type SkolemizationMap = FnvHashMap<ty::BoundRegion,ty::Region>;
112
113/// Why did we require that the two types be related?
114///
115/// See `error_reporting.rs` for more details
85aaf69f 116#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
117pub enum TypeOrigin {
118 // Not yet categorized in a better way
119 Misc(Span),
120
121 // Checking that method of impl is compatible with trait
122 MethodCompatCheck(Span),
123
124 // Checking that this expression can be assigned where it needs to be
125 // FIXME(eddyb) #11161 is the original Expr required?
126 ExprAssignable(Span),
127
128 // Relating trait refs when resolving vtables
129 RelateTraitRefs(Span),
130
131 // Relating self types when resolving vtables
132 RelateSelfType(Span),
133
134 // Relating trait type parameters to those found in impl etc
135 RelateOutputImplTypes(Span),
136
137 // Computing common supertype in the arms of a match expression
138 MatchExpressionArm(Span, Span),
139
140 // Computing common supertype in an if expression
141 IfExpression(Span),
142
143 // Computing common supertype of an if expression with no else counter-part
144 IfExpressionWithNoElse(Span),
145
146 // Computing common supertype in a range expression
147 RangeExpression(Span),
148
149 // `where a == b`
150 EquatePredicate(Span),
151}
152
c34b1796
AL
153impl TypeOrigin {
154 fn as_str(&self) -> &'static str {
155 match self {
156 &TypeOrigin::Misc(_) |
157 &TypeOrigin::RelateSelfType(_) |
158 &TypeOrigin::RelateOutputImplTypes(_) |
159 &TypeOrigin::ExprAssignable(_) => "mismatched types",
160 &TypeOrigin::RelateTraitRefs(_) => "mismatched traits",
161 &TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait",
162 &TypeOrigin::MatchExpressionArm(_, _) => "match arms have incompatible types",
163 &TypeOrigin::IfExpression(_) => "if and else have incompatible types",
164 &TypeOrigin::IfExpressionWithNoElse(_) => "if may be missing an else clause",
165 &TypeOrigin::RangeExpression(_) => "start and end of range have incompatible types",
166 &TypeOrigin::EquatePredicate(_) => "equality predicate not satisfied",
167 }
168 }
169}
170
171impl fmt::Display for TypeOrigin {
172 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(),fmt::Error> {
173 fmt::Display::fmt(self.as_str(), f)
174 }
175}
176
1a4d82fc 177/// See `error_reporting.rs` for more details
85aaf69f 178#[derive(Clone, Debug)]
1a4d82fc 179pub enum ValuePairs<'tcx> {
e9174d1e
SL
180 Types(ExpectedFound<Ty<'tcx>>),
181 TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
182 PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
1a4d82fc
JJ
183}
184
185/// The trace designates the path through inference that we took to
186/// encounter an error or subtyping constraint.
187///
188/// See `error_reporting.rs` for more details.
62682a34 189#[derive(Clone)]
1a4d82fc
JJ
190pub struct TypeTrace<'tcx> {
191 origin: TypeOrigin,
192 values: ValuePairs<'tcx>,
193}
194
195/// The origin of a `r1 <= r2` constraint.
196///
197/// See `error_reporting.rs` for more details
85aaf69f 198#[derive(Clone, Debug)]
1a4d82fc 199pub enum SubregionOrigin<'tcx> {
e9174d1e
SL
200 // Marker to indicate a constraint that only arises due to new
201 // provisions from RFC 1214. This will result in a warning, not an
202 // error.
203 RFC1214Subregion(Rc<SubregionOrigin<'tcx>>),
204
1a4d82fc
JJ
205 // Arose from a subtyping relation
206 Subtype(TypeTrace<'tcx>),
207
208 // Stack-allocated closures cannot outlive innermost loop
209 // or function so as to ensure we only require finite stack
210 InfStackClosure(Span),
211
212 // Invocation of closure must be within its lifetime
213 InvokeClosure(Span),
214
215 // Dereference of reference must be within its lifetime
216 DerefPointer(Span),
217
218 // Closure bound must not outlive captured free variables
219 FreeVariable(Span, ast::NodeId),
220
221 // Index into slice must be within its lifetime
222 IndexSlice(Span),
223
224 // When casting `&'a T` to an `&'b Trait` object,
225 // relating `'a` to `'b`
226 RelateObjectBound(Span),
227
228 // Some type parameter was instantiated with the given type,
229 // and that type must outlive some region.
230 RelateParamBound(Span, Ty<'tcx>),
231
232 // The given region parameter was instantiated with a region
233 // that must outlive some other region.
234 RelateRegionParamBound(Span),
235
236 // A bound placed on type parameters that states that must outlive
237 // the moment of their instantiation.
238 RelateDefaultParamBound(Span, Ty<'tcx>),
239
240 // Creating a pointer `b` to contents of another reference
241 Reborrow(Span),
242
243 // Creating a pointer `b` to contents of an upvar
244 ReborrowUpvar(Span, ty::UpvarId),
245
e9174d1e
SL
246 // Data with type `Ty<'tcx>` was borrowed
247 DataBorrowed(Ty<'tcx>, Span),
248
1a4d82fc
JJ
249 // (&'a &'b T) where a >= b
250 ReferenceOutlivesReferent(Ty<'tcx>, Span),
251
e9174d1e
SL
252 // Type or region parameters must be in scope.
253 ParameterInScope(ParameterOrigin, Span),
254
1a4d82fc
JJ
255 // The type T of an expression E must outlive the lifetime for E.
256 ExprTypeIsNotInScope(Ty<'tcx>, Span),
257
258 // A `ref b` whose region does not enclose the decl site
259 BindingTypeIsNotValidAtDecl(Span),
260
261 // Regions appearing in a method receiver must outlive method call
262 CallRcvr(Span),
263
264 // Regions appearing in a function argument must outlive func call
265 CallArg(Span),
266
267 // Region in return type of invoked fn must enclose call
268 CallReturn(Span),
269
85aaf69f
SL
270 // Operands must be in scope
271 Operand(Span),
272
1a4d82fc
JJ
273 // Region resulting from a `&` expr must enclose the `&` expr
274 AddrOf(Span),
275
276 // An auto-borrow that does not enclose the expr where it occurs
277 AutoBorrow(Span),
85aaf69f
SL
278
279 // Region constraint arriving from destructor safety
280 SafeDestructor(Span),
1a4d82fc
JJ
281}
282
e9174d1e
SL
283/// Places that type/region parameters can appear.
284#[derive(Clone, Copy, Debug)]
285pub enum ParameterOrigin {
286 Path, // foo::bar
287 MethodCall, // foo.bar() <-- parameters on impl providing bar()
288 OverloadedOperator, // a + b when overloaded
289 OverloadedDeref, // *a when overloaded
290}
291
1a4d82fc 292/// Times when we replace late-bound regions with variables:
85aaf69f 293#[derive(Clone, Copy, Debug)]
1a4d82fc
JJ
294pub enum LateBoundRegionConversionTime {
295 /// when a fn is called
296 FnCall,
297
298 /// when two higher-ranked types are compared
299 HigherRankedType,
300
301 /// when projecting an associated type
302 AssocTypeProjection(ast::Name),
303}
304
305/// Reasons to create a region inference variable
306///
307/// See `error_reporting.rs` for more details
85aaf69f 308#[derive(Clone, Debug)]
c34b1796 309pub enum RegionVariableOrigin {
1a4d82fc
JJ
310 // Region variables created for ill-categorized reasons,
311 // mostly indicates places in need of refactoring
312 MiscVariable(Span),
313
314 // Regions created by a `&P` or `[...]` pattern
315 PatternRegion(Span),
316
317 // Regions created by `&` operator
318 AddrOfRegion(Span),
319
1a4d82fc
JJ
320 // Regions created as part of an autoref of a method receiver
321 Autoref(Span),
322
323 // Regions created as part of an automatic coercion
c34b1796 324 Coercion(Span),
1a4d82fc
JJ
325
326 // Region variables created as the values for early-bound regions
327 EarlyBoundRegion(Span, ast::Name),
328
329 // Region variables created for bound regions
330 // in a function or method that is called
331 LateBoundRegion(Span, ty::BoundRegion, LateBoundRegionConversionTime),
332
333 UpvarRegion(ty::UpvarId, Span),
334
335 BoundRegionInCoherence(ast::Name),
336}
337
c34b1796 338#[derive(Copy, Clone, Debug)]
c1a9b12d
SL
339pub enum FixupError {
340 UnresolvedIntTy(IntVid),
341 UnresolvedFloatTy(FloatVid),
342 UnresolvedTy(TyVid)
1a4d82fc
JJ
343}
344
c1a9b12d
SL
345pub fn fixup_err_to_string(f: FixupError) -> String {
346 use self::FixupError::*;
347
1a4d82fc 348 match f {
c1a9b12d 349 UnresolvedIntTy(_) => {
1a4d82fc
JJ
350 "cannot determine the type of this integer; add a suffix to \
351 specify the type explicitly".to_string()
352 }
c1a9b12d 353 UnresolvedFloatTy(_) => {
1a4d82fc
JJ
354 "cannot determine the type of this number; add a suffix to specify \
355 the type explicitly".to_string()
356 }
c1a9b12d 357 UnresolvedTy(_) => "unconstrained type".to_string(),
1a4d82fc
JJ
358 }
359}
360
c1a9b12d
SL
361/// errors_will_be_reported is required to proxy to the fulfillment context
362/// FIXME -- a better option would be to hold back on modifying
363/// the global cache until we know that all dependent obligations
364/// are also satisfied. In that case, we could actually remove
365/// this boolean flag, and we'd also avoid the problem of squelching
366/// duplicate errors that occur across fns.
367pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
368 tables: &'a RefCell<ty::Tables<'tcx>>,
369 param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>,
370 errors_will_be_reported: bool)
1a4d82fc
JJ
371 -> InferCtxt<'a, 'tcx> {
372 InferCtxt {
373 tcx: tcx,
c1a9b12d 374 tables: tables,
1a4d82fc
JJ
375 type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
376 int_unification_table: RefCell::new(UnificationTable::new()),
377 float_unification_table: RefCell::new(UnificationTable::new()),
378 region_vars: RegionVarBindings::new(tcx),
c1a9b12d
SL
379 parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
380 fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
e9174d1e 381 reported_trait_errors: RefCell::new(FnvHashSet()),
c1a9b12d
SL
382 normalize: false,
383 err_count_on_creation: tcx.sess.err_count()
1a4d82fc
JJ
384 }
385}
386
c1a9b12d
SL
387pub fn normalizing_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
388 tables: &'a RefCell<ty::Tables<'tcx>>)
389 -> InferCtxt<'a, 'tcx> {
390 let mut infcx = new_infer_ctxt(tcx, tables, None, false);
391 infcx.normalize = true;
392 infcx
393}
394
1a4d82fc
JJ
395/// Computes the least upper-bound of `a` and `b`. If this is not possible, reports an error and
396/// returns ty::err.
397pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
398 origin: TypeOrigin,
399 a_is_expected: bool,
400 a: Ty<'tcx>,
401 b: Ty<'tcx>)
402 -> Ty<'tcx>
403{
62682a34
SL
404 debug!("common_supertype({:?}, {:?})",
405 a, b);
1a4d82fc
JJ
406
407 let trace = TypeTrace {
408 origin: origin,
409 values: Types(expected_found(a_is_expected, a, b))
410 };
411
c34b1796 412 let result = cx.commit_if_ok(|_| cx.lub(a_is_expected, trace.clone()).relate(&a, &b));
1a4d82fc
JJ
413 match result {
414 Ok(t) => t,
415 Err(ref err) => {
416 cx.report_and_explain_type_error(trace, err);
417 cx.tcx.types.err
418 }
419 }
420}
421
422pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
423 a_is_expected: bool,
424 origin: TypeOrigin,
425 a: Ty<'tcx>,
426 b: Ty<'tcx>)
c34b1796 427 -> UnitResult<'tcx>
1a4d82fc 428{
62682a34 429 debug!("mk_subty({:?} <: {:?})", a, b);
c34b1796 430 cx.sub_types(a_is_expected, origin, a, b)
1a4d82fc
JJ
431}
432
433pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
434 a: Ty<'tcx>,
435 b: Ty<'tcx>)
c34b1796 436 -> UnitResult<'tcx> {
62682a34 437 debug!("can_mk_subty({:?} <: {:?})", a, b);
1a4d82fc
JJ
438 cx.probe(|_| {
439 let trace = TypeTrace {
440 origin: Misc(codemap::DUMMY_SP),
441 values: Types(expected_found(true, a, b))
442 };
c34b1796 443 cx.sub(true, trace).relate(&a, &b).map(|_| ())
1a4d82fc
JJ
444 })
445}
446
c34b1796
AL
447pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
448 -> UnitResult<'tcx>
1a4d82fc
JJ
449{
450 cx.can_equate(&a, &b)
451}
452
453pub fn mk_subr<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
454 origin: SubregionOrigin<'tcx>,
455 a: ty::Region,
456 b: ty::Region) {
62682a34 457 debug!("mk_subr({:?} <: {:?})", a, b);
1a4d82fc
JJ
458 let snapshot = cx.region_vars.start_snapshot();
459 cx.region_vars.make_subregion(origin, a, b);
460 cx.region_vars.commit(snapshot);
461}
462
463pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
464 a_is_expected: bool,
465 origin: TypeOrigin,
466 a: Ty<'tcx>,
467 b: Ty<'tcx>)
c34b1796 468 -> UnitResult<'tcx>
1a4d82fc 469{
62682a34 470 debug!("mk_eqty({:?} <: {:?})", a, b);
c34b1796 471 cx.commit_if_ok(|_| cx.eq_types(a_is_expected, origin, a, b))
1a4d82fc
JJ
472}
473
474pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
475 a_is_expected: bool,
476 origin: TypeOrigin,
477 a: ty::PolyTraitRef<'tcx>,
478 b: ty::PolyTraitRef<'tcx>)
c34b1796 479 -> UnitResult<'tcx>
1a4d82fc 480{
62682a34
SL
481 debug!("mk_sub_trait_refs({:?} <: {:?})",
482 a, b);
c34b1796 483 cx.commit_if_ok(|_| cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
1a4d82fc
JJ
484}
485
486fn expected_found<T>(a_is_expected: bool,
487 a: T,
488 b: T)
e9174d1e 489 -> ExpectedFound<T>
1a4d82fc
JJ
490{
491 if a_is_expected {
e9174d1e 492 ExpectedFound {expected: a, found: b}
1a4d82fc 493 } else {
e9174d1e 494 ExpectedFound {expected: b, found: a}
1a4d82fc
JJ
495 }
496}
497
1a4d82fc
JJ
498#[must_use = "once you start a snapshot, you should always consume it"]
499pub struct CombinedSnapshot {
500 type_snapshot: type_variable::Snapshot,
501 int_snapshot: unify::Snapshot<ty::IntVid>,
502 float_snapshot: unify::Snapshot<ty::FloatVid>,
503 region_vars_snapshot: RegionSnapshot,
504}
505
c1a9b12d
SL
506pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
507 where T : TypeFoldable<'tcx> + HasTypeFlags
508{
509 debug!("normalize_associated_type(t={:?})", value);
510
e9174d1e 511 let value = tcx.erase_regions(value);
c1a9b12d
SL
512
513 if !value.has_projection_types() {
514 return value;
515 }
516
517 let infcx = new_infer_ctxt(tcx, &tcx.tables, None, true);
518 let mut selcx = traits::SelectionContext::new(&infcx);
519 let cause = traits::ObligationCause::dummy();
520 let traits::Normalized { value: result, obligations } =
521 traits::normalize(&mut selcx, cause, &value);
522
523 debug!("normalize_associated_type: result={:?} obligations={:?}",
524 result,
525 obligations);
526
527 let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
528
529 for obligation in obligations {
530 fulfill_cx.register_predicate_obligation(&infcx, obligation);
531 }
532
e9174d1e 533 drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result)
c1a9b12d
SL
534}
535
536pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
537 infcx: &InferCtxt<'a,'tcx>,
538 fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
539 result: &T)
540 -> T
e9174d1e 541 where T : TypeFoldable<'tcx> + HasTypeFlags
c1a9b12d
SL
542{
543 match drain_fulfillment_cx(infcx, fulfill_cx, result) {
544 Ok(v) => v,
545 Err(errors) => {
546 infcx.tcx.sess.span_bug(
547 span,
548 &format!("Encountered errors `{:?}` fulfilling during trans",
549 errors));
550 }
551 }
552}
553
554/// Finishes processes any obligations that remain in the fulfillment
555/// context, and then "freshens" and returns `result`. This is
556/// primarily used during normalization and other cases where
557/// processing the obligations in `fulfill_cx` may cause type
558/// inference variables that appear in `result` to be unified, and
559/// hence we need to process those obligations to get the complete
560/// picture of the type.
561pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
562 fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
563 result: &T)
564 -> Result<T,Vec<traits::FulfillmentError<'tcx>>>
e9174d1e 565 where T : TypeFoldable<'tcx> + HasTypeFlags
c1a9b12d
SL
566{
567 debug!("drain_fulfillment_cx(result={:?})",
568 result);
569
570 // In principle, we only need to do this so long as `result`
571 // contains unbound type parameters. It could be a slight
572 // optimization to stop iterating early.
573 match fulfill_cx.select_all_or_error(infcx) {
574 Ok(()) => { }
575 Err(errors) => {
576 return Err(errors);
577 }
578 }
579
e9174d1e
SL
580 let result = infcx.resolve_type_vars_if_possible(result);
581 Ok(infcx.tcx.erase_regions(&result))
c1a9b12d
SL
582}
583
1a4d82fc
JJ
584impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
585 pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
586 t.fold_with(&mut self.freshener())
587 }
588
589 pub fn type_var_diverges(&'a self, ty: Ty) -> bool {
590 match ty.sty {
62682a34 591 ty::TyInfer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
1a4d82fc
JJ
592 _ => false
593 }
594 }
595
596 pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
597 freshen::TypeFreshener::new(self)
598 }
599
600 pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
e9174d1e
SL
601 use middle::ty::error::UnconstrainedNumeric::Neither;
602 use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
1a4d82fc 603 match ty.sty {
62682a34 604 ty::TyInfer(ty::IntVar(vid)) => {
c34b1796
AL
605 if self.int_unification_table.borrow_mut().has_value(vid) {
606 Neither
607 } else {
608 UnconstrainedInt
1a4d82fc
JJ
609 }
610 },
62682a34 611 ty::TyInfer(ty::FloatVar(vid)) => {
c34b1796
AL
612 if self.float_unification_table.borrow_mut().has_value(vid) {
613 Neither
614 } else {
615 UnconstrainedFloat
1a4d82fc
JJ
616 }
617 },
618 _ => Neither,
619 }
620 }
621
c1a9b12d
SL
622 /// Returns a type variable's default fallback if any exists. A default
623 /// must be attached to the variable when created, if it is created
624 /// without a default, this will return None.
625 ///
626 /// This code does not apply to integral or floating point variables,
627 /// only to use declared defaults.
628 ///
629 /// See `new_ty_var_with_default` to create a type variable with a default.
630 /// See `type_variable::Default` for details about what a default entails.
631 pub fn default(&self, ty: Ty<'tcx>) -> Option<type_variable::Default<'tcx>> {
632 match ty.sty {
633 ty::TyInfer(ty::TyVar(vid)) => self.type_variables.borrow().default(vid),
634 _ => None
635 }
636 }
637
638 pub fn unsolved_variables(&self) -> Vec<ty::Ty<'tcx>> {
639 let mut variables = Vec::new();
640
641 let unbound_ty_vars = self.type_variables
642 .borrow()
643 .unsolved_variables()
644 .into_iter()
645 .map(|t| self.tcx.mk_var(t));
646
647 let unbound_int_vars = self.int_unification_table
648 .borrow_mut()
649 .unsolved_variables()
650 .into_iter()
651 .map(|v| self.tcx.mk_int_var(v));
652
653 let unbound_float_vars = self.float_unification_table
654 .borrow_mut()
655 .unsolved_variables()
656 .into_iter()
657 .map(|v| self.tcx.mk_float_var(v));
658
659 variables.extend(unbound_ty_vars);
660 variables.extend(unbound_int_vars);
661 variables.extend(unbound_float_vars);
662
663 return variables;
664 }
665
c34b1796
AL
666 fn combine_fields(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
667 -> CombineFields<'a, 'tcx> {
1a4d82fc
JJ
668 CombineFields {infcx: self,
669 a_is_expected: a_is_expected,
62682a34
SL
670 trace: trace,
671 cause: None}
1a4d82fc
JJ
672 }
673
c34b1796
AL
674 // public so that it can be used from the rustc_driver unit tests
675 pub fn equate(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
676 -> equate::Equate<'a, 'tcx>
677 {
678 self.combine_fields(a_is_expected, trace).equate()
679 }
680
681 // public so that it can be used from the rustc_driver unit tests
682 pub fn sub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
683 -> sub::Sub<'a, 'tcx>
684 {
685 self.combine_fields(a_is_expected, trace).sub()
1a4d82fc
JJ
686 }
687
c34b1796
AL
688 // public so that it can be used from the rustc_driver unit tests
689 pub fn lub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
690 -> lub::Lub<'a, 'tcx>
691 {
692 self.combine_fields(a_is_expected, trace).lub()
1a4d82fc
JJ
693 }
694
c34b1796
AL
695 // public so that it can be used from the rustc_driver unit tests
696 pub fn glb(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
697 -> glb::Glb<'a, 'tcx>
698 {
699 self.combine_fields(a_is_expected, trace).glb()
1a4d82fc
JJ
700 }
701
702 fn start_snapshot(&self) -> CombinedSnapshot {
703 CombinedSnapshot {
704 type_snapshot: self.type_variables.borrow_mut().snapshot(),
705 int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
706 float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
707 region_vars_snapshot: self.region_vars.start_snapshot(),
708 }
709 }
710
c1a9b12d
SL
711 fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot) {
712 debug!("rollback_to(cause={})", cause);
1a4d82fc
JJ
713 let CombinedSnapshot { type_snapshot,
714 int_snapshot,
715 float_snapshot,
716 region_vars_snapshot } = snapshot;
717
718 self.type_variables
719 .borrow_mut()
720 .rollback_to(type_snapshot);
721 self.int_unification_table
722 .borrow_mut()
723 .rollback_to(int_snapshot);
724 self.float_unification_table
725 .borrow_mut()
726 .rollback_to(float_snapshot);
727 self.region_vars
728 .rollback_to(region_vars_snapshot);
729 }
730
731 fn commit_from(&self, snapshot: CombinedSnapshot) {
732 debug!("commit_from!");
733 let CombinedSnapshot { type_snapshot,
734 int_snapshot,
735 float_snapshot,
736 region_vars_snapshot } = snapshot;
737
738 self.type_variables
739 .borrow_mut()
740 .commit(type_snapshot);
741 self.int_unification_table
742 .borrow_mut()
743 .commit(int_snapshot);
744 self.float_unification_table
745 .borrow_mut()
746 .commit(float_snapshot);
747 self.region_vars
748 .commit(region_vars_snapshot);
749 }
750
751 /// Execute `f` and commit the bindings
752 pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
753 F: FnOnce() -> R,
754 {
755 debug!("commit()");
756 let snapshot = self.start_snapshot();
757 let r = f();
758 self.commit_from(snapshot);
759 r
760 }
761
c34b1796 762 /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`
1a4d82fc 763 pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
c34b1796 764 F: FnOnce(&CombinedSnapshot) -> Result<T, E>
1a4d82fc 765 {
c34b1796
AL
766 debug!("commit_if_ok()");
767 let snapshot = self.start_snapshot();
768 let r = f(&snapshot);
769 debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
770 match r {
771 Ok(_) => { self.commit_from(snapshot); }
c1a9b12d 772 Err(_) => { self.rollback_to("commit_if_ok -- error", snapshot); }
c34b1796
AL
773 }
774 r
1a4d82fc
JJ
775 }
776
85aaf69f
SL
777 /// Execute `f` and commit only the region bindings if successful.
778 /// The function f must be very careful not to leak any non-region
779 /// variables that get created.
780 pub fn commit_regions_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
781 F: FnOnce() -> Result<T, E>
782 {
783 debug!("commit_regions_if_ok()");
784 let CombinedSnapshot { type_snapshot,
785 int_snapshot,
786 float_snapshot,
787 region_vars_snapshot } = self.start_snapshot();
788
c34b1796 789 let r = self.commit_if_ok(|_| f());
85aaf69f 790
c1a9b12d
SL
791 debug!("commit_regions_if_ok: rolling back everything but regions");
792
85aaf69f
SL
793 // Roll back any non-region bindings - they should be resolved
794 // inside `f`, with, e.g. `resolve_type_vars_if_possible`.
795 self.type_variables
796 .borrow_mut()
797 .rollback_to(type_snapshot);
798 self.int_unification_table
799 .borrow_mut()
800 .rollback_to(int_snapshot);
801 self.float_unification_table
802 .borrow_mut()
803 .rollback_to(float_snapshot);
804
805 // Commit region vars that may escape through resolved types.
806 self.region_vars
807 .commit(region_vars_snapshot);
808
809 r
810 }
811
1a4d82fc
JJ
812 /// Execute `f` then unroll any bindings it creates
813 pub fn probe<R, F>(&self, f: F) -> R where
814 F: FnOnce(&CombinedSnapshot) -> R,
815 {
816 debug!("probe()");
817 let snapshot = self.start_snapshot();
818 let r = f(&snapshot);
c1a9b12d 819 self.rollback_to("probe", snapshot);
1a4d82fc
JJ
820 r
821 }
822
823 pub fn add_given(&self,
824 sub: ty::FreeRegion,
825 sup: ty::RegionVid)
826 {
827 self.region_vars.add_given(sub, sup);
828 }
829
830 pub fn sub_types(&self,
831 a_is_expected: bool,
832 origin: TypeOrigin,
833 a: Ty<'tcx>,
834 b: Ty<'tcx>)
c34b1796 835 -> UnitResult<'tcx>
1a4d82fc 836 {
62682a34 837 debug!("sub_types({:?} <: {:?})", a, b);
c34b1796 838 self.commit_if_ok(|_| {
85aaf69f 839 let trace = TypeTrace::types(origin, a_is_expected, a, b);
c34b1796 840 self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
1a4d82fc
JJ
841 })
842 }
843
844 pub fn eq_types(&self,
845 a_is_expected: bool,
846 origin: TypeOrigin,
847 a: Ty<'tcx>,
848 b: Ty<'tcx>)
c34b1796 849 -> UnitResult<'tcx>
1a4d82fc 850 {
c34b1796 851 self.commit_if_ok(|_| {
85aaf69f 852 let trace = TypeTrace::types(origin, a_is_expected, a, b);
c34b1796 853 self.equate(a_is_expected, trace).relate(&a, &b).map(|_| ())
1a4d82fc
JJ
854 })
855 }
856
857 pub fn sub_trait_refs(&self,
858 a_is_expected: bool,
859 origin: TypeOrigin,
d9579d0f
AL
860 a: ty::TraitRef<'tcx>,
861 b: ty::TraitRef<'tcx>)
c34b1796 862 -> UnitResult<'tcx>
1a4d82fc 863 {
62682a34
SL
864 debug!("sub_trait_refs({:?} <: {:?})",
865 a,
866 b);
c34b1796 867 self.commit_if_ok(|_| {
1a4d82fc
JJ
868 let trace = TypeTrace {
869 origin: origin,
870 values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
871 };
d9579d0f 872 self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
1a4d82fc
JJ
873 })
874 }
875
876 pub fn sub_poly_trait_refs(&self,
877 a_is_expected: bool,
878 origin: TypeOrigin,
879 a: ty::PolyTraitRef<'tcx>,
880 b: ty::PolyTraitRef<'tcx>)
c34b1796 881 -> UnitResult<'tcx>
1a4d82fc 882 {
62682a34
SL
883 debug!("sub_poly_trait_refs({:?} <: {:?})",
884 a,
885 b);
c34b1796 886 self.commit_if_ok(|_| {
1a4d82fc
JJ
887 let trace = TypeTrace {
888 origin: origin,
889 values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
890 };
c34b1796 891 self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
1a4d82fc
JJ
892 })
893 }
894
895 pub fn skolemize_late_bound_regions<T>(&self,
896 value: &ty::Binder<T>,
897 snapshot: &CombinedSnapshot)
898 -> (T, SkolemizationMap)
62682a34 899 where T : TypeFoldable<'tcx>
1a4d82fc
JJ
900 {
901 /*! See `higher_ranked::skolemize_late_bound_regions` */
902
903 higher_ranked::skolemize_late_bound_regions(self, value, snapshot)
904 }
905
906 pub fn leak_check(&self,
907 skol_map: &SkolemizationMap,
908 snapshot: &CombinedSnapshot)
c34b1796 909 -> UnitResult<'tcx>
1a4d82fc
JJ
910 {
911 /*! See `higher_ranked::leak_check` */
912
913 match higher_ranked::leak_check(self, skol_map, snapshot) {
914 Ok(()) => Ok(()),
c1a9b12d 915 Err((br, r)) => Err(TypeError::RegionsInsufficientlyPolymorphic(br, r))
1a4d82fc
JJ
916 }
917 }
918
919 pub fn plug_leaks<T>(&self,
920 skol_map: SkolemizationMap,
921 snapshot: &CombinedSnapshot,
922 value: &T)
923 -> T
e9174d1e 924 where T : TypeFoldable<'tcx> + HasTypeFlags
1a4d82fc
JJ
925 {
926 /*! See `higher_ranked::plug_leaks` */
927
928 higher_ranked::plug_leaks(self, skol_map, snapshot, value)
929 }
930
931 pub fn equality_predicate(&self,
932 span: Span,
933 predicate: &ty::PolyEquatePredicate<'tcx>)
c34b1796
AL
934 -> UnitResult<'tcx> {
935 self.commit_if_ok(|snapshot| {
1a4d82fc
JJ
936 let (ty::EquatePredicate(a, b), skol_map) =
937 self.skolemize_late_bound_regions(predicate, snapshot);
938 let origin = EquatePredicate(span);
939 let () = try!(mk_eqty(self, false, origin, a, b));
940 self.leak_check(&skol_map, snapshot)
941 })
942 }
943
944 pub fn region_outlives_predicate(&self,
945 span: Span,
946 predicate: &ty::PolyRegionOutlivesPredicate)
c34b1796
AL
947 -> UnitResult<'tcx> {
948 self.commit_if_ok(|snapshot| {
1a4d82fc
JJ
949 let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
950 self.skolemize_late_bound_regions(predicate, snapshot);
951 let origin = RelateRegionParamBound(span);
952 let () = mk_subr(self, origin, r_b, r_a); // `b : a` ==> `a <= b`
953 self.leak_check(&skol_map, snapshot)
954 })
955 }
956
957 pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
958 self.type_variables
959 .borrow_mut()
c1a9b12d 960 .new_var(diverging, None)
1a4d82fc
JJ
961 }
962
963 pub fn next_ty_var(&self) -> Ty<'tcx> {
c1a9b12d
SL
964 self.tcx.mk_var(self.next_ty_var_id(false))
965 }
966
967 pub fn next_ty_var_with_default(&self,
968 default: Option<type_variable::Default<'tcx>>) -> Ty<'tcx> {
969 let ty_var_id = self.type_variables
970 .borrow_mut()
971 .new_var(false, default);
972
973 self.tcx.mk_var(ty_var_id)
1a4d82fc
JJ
974 }
975
976 pub fn next_diverging_ty_var(&self) -> Ty<'tcx> {
c1a9b12d 977 self.tcx.mk_var(self.next_ty_var_id(true))
1a4d82fc
JJ
978 }
979
c34b1796 980 pub fn next_ty_vars(&self, n: usize) -> Vec<Ty<'tcx>> {
85aaf69f 981 (0..n).map(|_i| self.next_ty_var()).collect()
1a4d82fc
JJ
982 }
983
984 pub fn next_int_var_id(&self) -> IntVid {
985 self.int_unification_table
986 .borrow_mut()
987 .new_key(None)
988 }
989
990 pub fn next_float_var_id(&self) -> FloatVid {
991 self.float_unification_table
992 .borrow_mut()
993 .new_key(None)
994 }
995
c34b1796 996 pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
e9174d1e 997 ty::ReVar(self.region_vars.new_region_var(origin))
1a4d82fc
JJ
998 }
999
1000 pub fn region_vars_for_defs(&self,
1001 span: Span,
1002 defs: &[ty::RegionParameterDef])
1003 -> Vec<ty::Region> {
1004 defs.iter()
1005 .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
1006 .collect()
1007 }
1008
c1a9b12d
SL
1009 // We have to take `&mut Substs` in order to provide the correct substitutions for defaults
1010 // along the way, for this reason we don't return them.
1011 pub fn type_vars_for_defs(&self,
1012 span: Span,
1013 space: subst::ParamSpace,
1014 substs: &mut Substs<'tcx>,
1015 defs: &[ty::TypeParameterDef<'tcx>]) {
1016
1017 let mut vars = Vec::with_capacity(defs.len());
1018
1019 for def in defs.iter() {
1020 let default = def.default.map(|default| {
1021 type_variable::Default {
1022 ty: default.subst_spanned(self.tcx, substs, Some(span)),
1023 origin_span: span,
1024 def_id: def.default_def_id
1025 }
1026 });
1027
1028 let ty_var = self.next_ty_var_with_default(default);
1029 substs.types.push(space, ty_var);
1030 vars.push(ty_var)
1031 }
1032 }
1033
1a4d82fc
JJ
1034 /// Given a set of generics defined on a type or impl, returns a substitution mapping each
1035 /// type/region parameter to a fresh inference variable.
1036 pub fn fresh_substs_for_generics(&self,
1037 span: Span,
1038 generics: &ty::Generics<'tcx>)
1039 -> subst::Substs<'tcx>
1040 {
c1a9b12d
SL
1041 let type_params = subst::VecPerParamSpace::empty();
1042
1a4d82fc
JJ
1043 let region_params =
1044 generics.regions.map(
1045 |d| self.next_region_var(EarlyBoundRegion(span, d.name)));
c1a9b12d
SL
1046
1047 let mut substs = subst::Substs::new(type_params, region_params);
1048
1049 for space in subst::ParamSpace::all().iter() {
1050 self.type_vars_for_defs(
1051 span,
1052 *space,
1053 &mut substs,
1054 generics.types.get_slice(*space));
1055 }
1056
1057 return substs;
1a4d82fc
JJ
1058 }
1059
1060 /// Given a set of generics defined on a trait, returns a substitution mapping each output
1061 /// type/region parameter to a fresh inference variable, and mapping the self type to
1062 /// `self_ty`.
1063 pub fn fresh_substs_for_trait(&self,
1064 span: Span,
1065 generics: &ty::Generics<'tcx>,
1066 self_ty: Ty<'tcx>)
1067 -> subst::Substs<'tcx>
1068 {
1069
1070 assert!(generics.types.len(subst::SelfSpace) == 1);
1071 assert!(generics.types.len(subst::FnSpace) == 0);
1072 assert!(generics.regions.len(subst::SelfSpace) == 0);
1073 assert!(generics.regions.len(subst::FnSpace) == 0);
1074
c1a9b12d 1075 let type_params = Vec::new();
1a4d82fc
JJ
1076
1077 let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
1078 let regions = self.region_vars_for_defs(span, region_param_defs);
1079
c1a9b12d
SL
1080 let mut substs = subst::Substs::new_trait(type_params, regions, self_ty);
1081
1082 let type_parameter_defs = generics.types.get_slice(subst::TypeSpace);
1083 self.type_vars_for_defs(span, subst::TypeSpace, &mut substs, type_parameter_defs);
1084
1085 return substs;
1a4d82fc
JJ
1086 }
1087
1088 pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
1089 self.region_vars.new_bound(debruijn)
1090 }
1091
c1a9b12d
SL
1092 /// Apply `adjustment` to the type of `expr`
1093 pub fn adjust_expr_ty(&self,
e9174d1e
SL
1094 expr: &hir::Expr,
1095 adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
c1a9b12d
SL
1096 -> Ty<'tcx>
1097 {
1098 let raw_ty = self.expr_ty(expr);
1099 let raw_ty = self.shallow_resolve(raw_ty);
1100 let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
1101 raw_ty.adjust(self.tcx,
1102 expr.span,
1103 expr.id,
1104 adjustment,
1105 |method_call| self.tables
1106 .borrow()
1107 .method_map
1108 .get(&method_call)
1109 .map(|method| resolve_ty(method.ty)))
1110 }
1111
1112 pub fn node_type(&self, id: ast::NodeId) -> Ty<'tcx> {
1113 match self.tables.borrow().node_types.get(&id) {
1114 Some(&t) => t,
1115 // FIXME
1116 None if self.tcx.sess.err_count() - self.err_count_on_creation != 0 =>
1117 self.tcx.types.err,
1118 None => {
1119 self.tcx.sess.bug(
1120 &format!("no type for node {}: {} in fcx",
1121 id, self.tcx.map.node_to_string(id)));
1122 }
1123 }
1124 }
1125
e9174d1e 1126 pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
c1a9b12d
SL
1127 match self.tables.borrow().node_types.get(&ex.id) {
1128 Some(&t) => t,
1129 None => {
1130 self.tcx.sess.bug(&format!("no type for expr in fcx"));
1131 }
1132 }
1133 }
1134
bd371182
AL
1135 pub fn resolve_regions_and_report_errors(&self,
1136 free_regions: &FreeRegionMap,
1137 subject_node_id: ast::NodeId) {
1138 let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
1a4d82fc
JJ
1139 self.report_region_errors(&errors); // see error_reporting.rs
1140 }
1141
1142 pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
62682a34 1143 self.resolve_type_vars_if_possible(&t).to_string()
1a4d82fc
JJ
1144 }
1145
1146 pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
1147 let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
c1a9b12d 1148 format!("({})", tstrs.join(", "))
1a4d82fc
JJ
1149 }
1150
d9579d0f 1151 pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
62682a34 1152 self.resolve_type_vars_if_possible(t).to_string()
1a4d82fc
JJ
1153 }
1154
1155 pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
1156 match typ.sty {
62682a34 1157 ty::TyInfer(ty::TyVar(v)) => {
1a4d82fc
JJ
1158 // Not entirely obvious: if `typ` is a type variable,
1159 // it can be resolved to an int/float variable, which
1160 // can then be recursively resolved, hence the
1161 // recursion. Note though that we prevent type
1162 // variables from unifying to other type variables
1163 // directly (though they may be embedded
1164 // structurally), and we prevent cycles in any case,
1165 // so this recursion should always be of very limited
1166 // depth.
1167 self.type_variables.borrow()
1168 .probe(v)
1169 .map(|t| self.shallow_resolve(t))
1170 .unwrap_or(typ)
1171 }
1172
62682a34 1173 ty::TyInfer(ty::IntVar(v)) => {
c34b1796
AL
1174 self.int_unification_table
1175 .borrow_mut()
1176 .probe(v)
1177 .map(|v| v.to_type(self.tcx))
1a4d82fc
JJ
1178 .unwrap_or(typ)
1179 }
1180
62682a34 1181 ty::TyInfer(ty::FloatVar(v)) => {
c34b1796
AL
1182 self.float_unification_table
1183 .borrow_mut()
1184 .probe(v)
1185 .map(|v| v.to_type(self.tcx))
1a4d82fc
JJ
1186 .unwrap_or(typ)
1187 }
1188
1189 _ => {
1190 typ
1191 }
1192 }
1193 }
1194
e9174d1e
SL
1195 pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
1196 where T: TypeFoldable<'tcx> + HasTypeFlags
1197 {
1a4d82fc
JJ
1198 /*!
1199 * Where possible, replaces type/int/float variables in
1200 * `value` with their final value. Note that region variables
1201 * are unaffected. If a type variable has not been unified, it
1202 * is left as is. This is an idempotent operation that does
1203 * not affect inference state in any way and so you can do it
1204 * at will.
1205 */
1206
e9174d1e
SL
1207 if !value.needs_infer() {
1208 return value.clone(); // avoid duplicated subst-folding
1209 }
1a4d82fc
JJ
1210 let mut r = resolve::OpportunisticTypeResolver::new(self);
1211 value.fold_with(&mut r)
1212 }
1213
c1a9b12d
SL
1214 /// Resolves all type variables in `t` and then, if any were left
1215 /// unresolved, substitutes an error type. This is used after the
1216 /// main checking when doing a second pass before writeback. The
1217 /// justification is that writeback will produce an error for
1218 /// these unconstrained type variables.
1219 fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult<Ty<'tcx>> {
1220 let ty = self.resolve_type_vars_if_possible(t);
1221 if ty.references_error() || ty.is_ty_var() {
1222 debug!("resolve_type_vars_or_error: error from {:?}", ty);
1223 Err(())
1224 } else {
1225 Ok(ty)
1226 }
1227 }
1228
1229 pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {
1a4d82fc
JJ
1230 /*!
1231 * Attempts to resolve all type/region variables in
1232 * `value`. Region inference must have been run already (e.g.,
1233 * by calling `resolve_regions_and_report_errors`). If some
1234 * variable was never unified, an `Err` results.
1235 *
1236 * This method is idempotent, but it not typically not invoked
1237 * except during the writeback phase.
1238 */
1239
1240 resolve::fully_resolve(self, value)
1241 }
1242
1243 // [Note-Type-error-reporting]
62682a34 1244 // An invariant is that anytime the expected or actual type is TyError (the special
1a4d82fc
JJ
1245 // error type, meaning that an error occurred when typechecking this expression),
1246 // this is a derived error. The error cascaded from another error (that was already
1247 // reported), so it's not useful to display it to the user.
1248 // The following four methods -- type_error_message_str, type_error_message_str_with_expected,
1249 // type_error_message, and report_mismatched_types -- implement this logic.
62682a34 1250 // They check if either the actual or expected type is TyError, and don't print the error
1a4d82fc
JJ
1251 // in this case. The typechecker should only ever report type errors involving mismatched
1252 // types using one of these four methods, and should not call span_err directly for such
1253 // errors.
1254 pub fn type_error_message_str<M>(&self,
1255 sp: Span,
1256 mk_msg: M,
1257 actual_ty: String,
e9174d1e 1258 err: Option<&TypeError<'tcx>>) where
1a4d82fc
JJ
1259 M: FnOnce(Option<String>, String) -> String,
1260 {
1261 self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
1262 }
1263
1264 pub fn type_error_message_str_with_expected<M>(&self,
1265 sp: Span,
1266 mk_msg: M,
1267 expected_ty: Option<Ty<'tcx>>,
1268 actual_ty: String,
e9174d1e 1269 err: Option<&TypeError<'tcx>>) where
1a4d82fc
JJ
1270 M: FnOnce(Option<String>, String) -> String,
1271 {
1272 debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
1273
1274 let resolved_expected = expected_ty.map(|e_ty| self.resolve_type_vars_if_possible(&e_ty));
1275
c1a9b12d
SL
1276 if !resolved_expected.references_error() {
1277 let error_str = err.map_or("".to_string(), |t_err| {
1278 format!(" ({})", t_err)
1279 });
1a4d82fc 1280
c1a9b12d
SL
1281 self.tcx.sess.span_err(sp, &format!("{}{}",
1282 mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty),
1283 error_str));
1a4d82fc 1284
c1a9b12d
SL
1285 if let Some(err) = err {
1286 self.tcx.note_and_explain_type_err(err, sp)
1a4d82fc
JJ
1287 }
1288 }
1289 }
1290
1291 pub fn type_error_message<M>(&self,
1292 sp: Span,
1293 mk_msg: M,
1294 actual_ty: Ty<'tcx>,
e9174d1e 1295 err: Option<&TypeError<'tcx>>) where
1a4d82fc
JJ
1296 M: FnOnce(String) -> String,
1297 {
1298 let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
1299
62682a34 1300 // Don't report an error if actual type is TyError.
c1a9b12d 1301 if actual_ty.references_error() {
1a4d82fc
JJ
1302 return;
1303 }
1304
1305 self.type_error_message_str(sp,
1306 move |_e, a| { mk_msg(a) },
1307 self.ty_to_string(actual_ty), err);
1308 }
1309
1310 pub fn report_mismatched_types(&self,
1311 span: Span,
1312 expected: Ty<'tcx>,
1313 actual: Ty<'tcx>,
e9174d1e 1314 err: &TypeError<'tcx>) {
1a4d82fc
JJ
1315 let trace = TypeTrace {
1316 origin: Misc(span),
e9174d1e 1317 values: Types(ExpectedFound {
1a4d82fc
JJ
1318 expected: expected,
1319 found: actual
1320 })
1321 };
1322 self.report_and_explain_type_error(trace, err);
1323 }
1324
c1a9b12d
SL
1325 pub fn report_conflicting_default_types(&self,
1326 span: Span,
1327 expected: type_variable::Default<'tcx>,
1328 actual: type_variable::Default<'tcx>) {
1329 let trace = TypeTrace {
1330 origin: Misc(span),
e9174d1e 1331 values: Types(ExpectedFound {
c1a9b12d
SL
1332 expected: expected.ty,
1333 found: actual.ty
1334 })
1335 };
1336
1337 self.report_and_explain_type_error(trace,
e9174d1e 1338 &TypeError::TyParamDefaultMismatch(ExpectedFound {
c1a9b12d
SL
1339 expected: expected,
1340 found: actual
1341 }));
1342 }
1343
1a4d82fc
JJ
1344 pub fn replace_late_bound_regions_with_fresh_var<T>(
1345 &self,
1346 span: Span,
1347 lbrct: LateBoundRegionConversionTime,
1348 value: &ty::Binder<T>)
1349 -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
62682a34 1350 where T : TypeFoldable<'tcx>
1a4d82fc 1351 {
e9174d1e 1352 self.tcx.replace_late_bound_regions(
1a4d82fc
JJ
1353 value,
1354 |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
1355 }
1356
1357 /// See `verify_generic_bound` method in `region_inference`
1358 pub fn verify_generic_bound(&self,
1359 origin: SubregionOrigin<'tcx>,
1360 kind: GenericKind<'tcx>,
1361 a: ty::Region,
e9174d1e 1362 bound: VerifyBound) {
62682a34
SL
1363 debug!("verify_generic_bound({:?}, {:?} <: {:?})",
1364 kind,
1365 a,
e9174d1e 1366 bound);
1a4d82fc 1367
e9174d1e 1368 self.region_vars.verify_generic_bound(origin, kind, a, bound);
1a4d82fc
JJ
1369 }
1370
c34b1796 1371 pub fn can_equate<'b,T>(&'b self, a: &T, b: &T) -> UnitResult<'tcx>
62682a34 1372 where T: Relate<'b,'tcx> + fmt::Debug
1a4d82fc 1373 {
62682a34 1374 debug!("can_equate({:?}, {:?})", a, b);
1a4d82fc
JJ
1375 self.probe(|_| {
1376 // Gin up a dummy trace, since this won't be committed
1377 // anyhow. We should make this typetrace stuff more
1378 // generic so we don't have to do anything quite this
1379 // terrible.
1380 let e = self.tcx.types.err;
1381 let trace = TypeTrace { origin: Misc(codemap::DUMMY_SP),
1382 values: Types(expected_found(true, e, e)) };
c34b1796
AL
1383 self.equate(true, trace).relate(a, b)
1384 }).map(|_| ())
1a4d82fc 1385 }
c1a9b12d
SL
1386
1387 pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
1388 let ty = self.node_type(id);
1389 self.resolve_type_vars_or_error(&ty)
1390 }
1391
e9174d1e 1392 pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
c1a9b12d
SL
1393 let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
1394 self.resolve_type_vars_or_error(&ty)
1395 }
1396
e9174d1e
SL
1397 pub fn tables_are_tcx_tables(&self) -> bool {
1398 let tables: &RefCell<ty::Tables> = &self.tables;
1399 let tcx_tables: &RefCell<ty::Tables> = &self.tcx.tables;
1400 tables as *const _ == tcx_tables as *const _
1401 }
1402
c1a9b12d
SL
1403 pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
1404 let ty = self.resolve_type_vars_if_possible(&ty);
e9174d1e
SL
1405 if ty.needs_infer() ||
1406 (ty.has_closure_types() && !self.tables_are_tcx_tables()) {
1407 // this can get called from typeck (by euv), and moves_by_default
1408 // rightly refuses to work with inference variables, but
1409 // moves_by_default has a cache, which we want to use in other
1410 // cases.
1411 !traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
1412 } else {
1413 ty.moves_by_default(&self.parameter_environment, span)
1414 }
c1a9b12d
SL
1415 }
1416
1417 pub fn node_method_ty(&self, method_call: ty::MethodCall)
1418 -> Option<Ty<'tcx>> {
1419 self.tables
1420 .borrow()
1421 .method_map
1422 .get(&method_call)
1423 .map(|method| method.ty)
1424 .map(|ty| self.resolve_type_vars_if_possible(&ty))
1425 }
1426
1427 pub fn node_method_id(&self, method_call: ty::MethodCall)
e9174d1e 1428 -> Option<DefId> {
c1a9b12d
SL
1429 self.tables
1430 .borrow()
1431 .method_map
1432 .get(&method_call)
1433 .map(|method| method.def_id)
1434 }
1435
e9174d1e 1436 pub fn adjustments(&self) -> Ref<NodeMap<adjustment::AutoAdjustment<'tcx>>> {
c1a9b12d 1437 fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
e9174d1e 1438 -> &'a NodeMap<adjustment::AutoAdjustment<'tcx>> {
c1a9b12d
SL
1439 &tables.adjustments
1440 }
1441
1442 Ref::map(self.tables.borrow(), project_adjustments)
1443 }
1444
1445 pub fn is_method_call(&self, id: ast::NodeId) -> bool {
1446 self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
1447 }
1448
1449 pub fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
1450 self.tcx.region_maps.temporary_scope(rvalue_id)
1451 }
1452
1453 pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
1454 self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
1455 }
1456
1457 pub fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
1458 &self.parameter_environment
1459 }
1460
1461 pub fn closure_kind(&self,
e9174d1e 1462 def_id: DefId)
c1a9b12d
SL
1463 -> Option<ty::ClosureKind>
1464 {
1465 self.tables.borrow().closure_kinds.get(&def_id).cloned()
1466 }
1467
1468 pub fn closure_type(&self,
e9174d1e 1469 def_id: DefId,
c1a9b12d
SL
1470 substs: &ty::ClosureSubsts<'tcx>)
1471 -> ty::ClosureTy<'tcx>
1472 {
1473 let closure_ty = self.tables
1474 .borrow()
1475 .closure_tys
1476 .get(&def_id)
1477 .unwrap()
1478 .subst(self.tcx, &substs.func_substs);
1479
1480 if self.normalize {
1481 normalize_associated_type(&self.tcx, &closure_ty)
1482 } else {
1483 closure_ty
1484 }
1485 }
1a4d82fc
JJ
1486}
1487
1488impl<'tcx> TypeTrace<'tcx> {
1489 pub fn span(&self) -> Span {
1490 self.origin.span()
1491 }
1492
85aaf69f
SL
1493 pub fn types(origin: TypeOrigin,
1494 a_is_expected: bool,
1495 a: Ty<'tcx>,
1496 b: Ty<'tcx>)
1497 -> TypeTrace<'tcx> {
1498 TypeTrace {
1499 origin: origin,
1500 values: Types(expected_found(a_is_expected, a, b))
1501 }
1502 }
1503
1a4d82fc
JJ
1504 pub fn dummy(tcx: &ty::ctxt<'tcx>) -> TypeTrace<'tcx> {
1505 TypeTrace {
1506 origin: Misc(codemap::DUMMY_SP),
e9174d1e 1507 values: Types(ExpectedFound {
1a4d82fc
JJ
1508 expected: tcx.types.err,
1509 found: tcx.types.err,
1510 })
1511 }
1512 }
1513}
1514
62682a34
SL
1515impl<'tcx> fmt::Debug for TypeTrace<'tcx> {
1516 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1517 write!(f, "TypeTrace({:?})", self.origin)
1a4d82fc
JJ
1518 }
1519}
1520
1521impl TypeOrigin {
1522 pub fn span(&self) -> Span {
1523 match *self {
1524 MethodCompatCheck(span) => span,
1525 ExprAssignable(span) => span,
1526 Misc(span) => span,
1527 RelateTraitRefs(span) => span,
1528 RelateSelfType(span) => span,
1529 RelateOutputImplTypes(span) => span,
1530 MatchExpressionArm(match_span, _) => match_span,
1531 IfExpression(span) => span,
1532 IfExpressionWithNoElse(span) => span,
1533 RangeExpression(span) => span,
1534 EquatePredicate(span) => span,
1535 }
1536 }
1537}
1538
1a4d82fc
JJ
1539impl<'tcx> SubregionOrigin<'tcx> {
1540 pub fn span(&self) -> Span {
1541 match *self {
e9174d1e 1542 RFC1214Subregion(ref a) => a.span(),
1a4d82fc
JJ
1543 Subtype(ref a) => a.span(),
1544 InfStackClosure(a) => a,
1545 InvokeClosure(a) => a,
1546 DerefPointer(a) => a,
1547 FreeVariable(a, _) => a,
1548 IndexSlice(a) => a,
1549 RelateObjectBound(a) => a,
1550 RelateParamBound(a, _) => a,
1551 RelateRegionParamBound(a) => a,
1552 RelateDefaultParamBound(a, _) => a,
1553 Reborrow(a) => a,
1554 ReborrowUpvar(a, _) => a,
e9174d1e 1555 DataBorrowed(_, a) => a,
1a4d82fc 1556 ReferenceOutlivesReferent(_, a) => a,
e9174d1e 1557 ParameterInScope(_, a) => a,
1a4d82fc
JJ
1558 ExprTypeIsNotInScope(_, a) => a,
1559 BindingTypeIsNotValidAtDecl(a) => a,
1560 CallRcvr(a) => a,
1561 CallArg(a) => a,
1562 CallReturn(a) => a,
85aaf69f 1563 Operand(a) => a,
1a4d82fc
JJ
1564 AddrOf(a) => a,
1565 AutoBorrow(a) => a,
85aaf69f 1566 SafeDestructor(a) => a,
1a4d82fc
JJ
1567 }
1568 }
1569}
1570
c34b1796 1571impl RegionVariableOrigin {
1a4d82fc
JJ
1572 pub fn span(&self) -> Span {
1573 match *self {
1574 MiscVariable(a) => a,
1575 PatternRegion(a) => a,
1576 AddrOfRegion(a) => a,
1a4d82fc 1577 Autoref(a) => a,
c34b1796 1578 Coercion(a) => a,
1a4d82fc
JJ
1579 EarlyBoundRegion(a, _) => a,
1580 LateBoundRegion(a, _, _) => a,
1581 BoundRegionInCoherence(_) => codemap::DUMMY_SP,
1582 UpvarRegion(_, a) => a
1583 }
1584 }
1585}