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