]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/typeck/infer/mod.rs
7c04b371aaea084c9f8468c414b10105a1d71654
[rust.git] / src / librustc / middle / typeck / 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 doc.rs for documentation */
12
13 #![allow(non_camel_case_types)]
14
15 pub use middle::ty::IntVarValue;
16 pub use self::resolve::resolve_and_force_all_but_regions;
17 pub use self::resolve::{force_all, not_regions};
18 pub use self::resolve::{force_ivar};
19 pub use self::resolve::{force_tvar, force_rvar};
20 pub use self::resolve::{resolve_ivar, resolve_all};
21 pub use self::resolve::{resolve_nested_tvar};
22 pub use self::resolve::{resolve_rvar};
23 pub use self::skolemize::TypeSkolemizer;
24
25 use middle::subst;
26 use middle::subst::Substs;
27 use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
28 use middle::ty;
29 use middle::ty_fold;
30 use middle::ty_fold::{TypeFolder, TypeFoldable};
31 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
32 use std::cell::{RefCell};
33 use std::collections::HashMap;
34 use std::rc::Rc;
35 use syntax::ast;
36 use syntax::codemap;
37 use syntax::codemap::Span;
38 use util::common::indent;
39 use util::ppaux::{bound_region_to_string, ty_to_string, trait_ref_to_string, Repr};
40
41 use self::coercion::Coerce;
42 use self::combine::{Combine, CombineFields};
43 use self::region_inference::{RegionVarBindings, RegionSnapshot};
44 use self::resolve::{resolver};
45 use self::equate::Equate;
46 use self::sub::Sub;
47 use self::lub::Lub;
48 use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes};
49 use self::error_reporting::ErrorReporting;
50
51 pub mod coercion;
52 pub mod combine;
53 pub mod doc;
54 pub mod equate;
55 pub mod error_reporting;
56 pub mod glb;
57 pub mod lattice;
58 pub mod lub;
59 pub mod region_inference;
60 pub mod resolve;
61 mod skolemize;
62 pub mod sub;
63 pub mod test;
64 pub mod type_variable;
65 pub mod unify;
66
67 pub type Bound<T> = Option<T>;
68
69 pub type cres<T> = Result<T,ty::type_err>; // "combine result"
70 pub type ures = cres<()>; // "unify result"
71 pub type fres<T> = Result<T, fixup_err>; // "fixup result"
72 pub type CoerceResult = cres<Option<ty::AutoAdjustment>>;
73
74 pub struct InferCtxt<'a, 'tcx: 'a> {
75     pub tcx: &'a ty::ctxt<'tcx>,
76
77     // We instantiate UnificationTable with bounds<ty::t> 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>,
81
82     // Map from integral variable to the kind of integer it represents
83     int_unification_table:
84         RefCell<UnificationTable<ty::IntVid, Option<IntVarValue>>>,
85
86     // Map from floating variable to the kind of float it represents
87     float_unification_table:
88         RefCell<UnificationTable<ty::FloatVid, Option<ast::FloatTy>>>,
89
90     // For region variables.
91     region_vars:
92         RegionVarBindings<'a, 'tcx>,
93 }
94
95 /// Why did we require that the two types be related?
96 ///
97 /// See `error_reporting.rs` for more details
98 #[deriving(Clone)]
99 pub enum TypeOrigin {
100     // Not yet categorized in a better way
101     Misc(Span),
102
103     // Checking that method of impl is compatible with trait
104     MethodCompatCheck(Span),
105
106     // Checking that this expression can be assigned where it needs to be
107     // FIXME(eddyb) #11161 is the original Expr required?
108     ExprAssignable(Span),
109
110     // Relating trait refs when resolving vtables
111     RelateTraitRefs(Span),
112
113     // Relating self types when resolving vtables
114     RelateSelfType(Span),
115
116     // Relating trait type parameters to those found in impl etc
117     RelateOutputImplTypes(Span),
118
119     // Computing common supertype in the arms of a match expression
120     MatchExpressionArm(Span, Span),
121
122     // Computing common supertype in an if expression
123     IfExpression(Span),
124
125     // Computing common supertype of an if expression with no else counter-part
126     IfExpressionWithNoElse(Span)
127 }
128
129 /// See `error_reporting.rs` for more details
130 #[deriving(Clone)]
131 pub enum ValuePairs {
132     Types(ty::expected_found<ty::t>),
133     TraitRefs(ty::expected_found<Rc<ty::TraitRef>>),
134 }
135
136 /// The trace designates the path through inference that we took to
137 /// encounter an error or subtyping constraint.
138 ///
139 /// See `error_reporting.rs` for more details.
140 #[deriving(Clone)]
141 pub struct TypeTrace {
142     origin: TypeOrigin,
143     values: ValuePairs,
144 }
145
146 /// The origin of a `r1 <= r2` constraint.
147 ///
148 /// See `error_reporting.rs` for more details
149 #[deriving(Clone)]
150 pub enum SubregionOrigin {
151     // Arose from a subtyping relation
152     Subtype(TypeTrace),
153
154     // Stack-allocated closures cannot outlive innermost loop
155     // or function so as to ensure we only require finite stack
156     InfStackClosure(Span),
157
158     // Invocation of closure must be within its lifetime
159     InvokeClosure(Span),
160
161     // Dereference of reference must be within its lifetime
162     DerefPointer(Span),
163
164     // Closure bound must not outlive captured free variables
165     FreeVariable(Span, ast::NodeId),
166
167     // Proc upvars must be 'static
168     ProcCapture(Span, ast::NodeId),
169
170     // Index into slice must be within its lifetime
171     IndexSlice(Span),
172
173     // When casting `&'a T` to an `&'b Trait` object,
174     // relating `'a` to `'b`
175     RelateObjectBound(Span),
176
177     // When closing over a variable in a closure/proc, ensure that the
178     // type of the variable outlives the lifetime bound.
179     RelateProcBound(Span, ast::NodeId, ty::t),
180
181     // The given type parameter was instantiated with the given type,
182     // and that type must outlive some region.
183     RelateParamBound(Span, ty::ParamTy, ty::t),
184
185     // The given region parameter was instantiated with a region
186     // that must outlive some other region.
187     RelateRegionParamBound(Span),
188
189     // A bound placed on type parameters that states that must outlive
190     // the moment of their instantiation.
191     RelateDefaultParamBound(Span, ty::t),
192
193     // Creating a pointer `b` to contents of another reference
194     Reborrow(Span),
195
196     // Creating a pointer `b` to contents of an upvar
197     ReborrowUpvar(Span, ty::UpvarId),
198
199     // (&'a &'b T) where a >= b
200     ReferenceOutlivesReferent(ty::t, Span),
201
202     // The type T of an expression E must outlive the lifetime for E.
203     ExprTypeIsNotInScope(ty::t, Span),
204
205     // A `ref b` whose region does not enclose the decl site
206     BindingTypeIsNotValidAtDecl(Span),
207
208     // Regions appearing in a method receiver must outlive method call
209     CallRcvr(Span),
210
211     // Regions appearing in a function argument must outlive func call
212     CallArg(Span),
213
214     // Region in return type of invoked fn must enclose call
215     CallReturn(Span),
216
217     // Region resulting from a `&` expr must enclose the `&` expr
218     AddrOf(Span),
219
220     // An auto-borrow that does not enclose the expr where it occurs
221     AutoBorrow(Span),
222 }
223
224 /// Reasons to create a region inference variable
225 ///
226 /// See `error_reporting.rs` for more details
227 #[deriving(Clone)]
228 pub enum RegionVariableOrigin {
229     // Region variables created for ill-categorized reasons,
230     // mostly indicates places in need of refactoring
231     MiscVariable(Span),
232
233     // Regions created by a `&P` or `[...]` pattern
234     PatternRegion(Span),
235
236     // Regions created by `&` operator
237     AddrOfRegion(Span),
238
239     // Regions created by `&[...]` literal
240     AddrOfSlice(Span),
241
242     // Regions created as part of an autoref of a method receiver
243     Autoref(Span),
244
245     // Regions created as part of an automatic coercion
246     Coercion(TypeTrace),
247
248     // Region variables created as the values for early-bound regions
249     EarlyBoundRegion(Span, ast::Name),
250
251     // Region variables created for bound regions
252     // in a function or method that is called
253     LateBoundRegion(Span, ty::BoundRegion),
254
255     // Region variables created for bound regions
256     // when doing subtyping/lub/glb computations
257     BoundRegionInFnType(Span, ty::BoundRegion),
258
259     UpvarRegion(ty::UpvarId, Span),
260
261     BoundRegionInCoherence(ast::Name),
262 }
263
264 #[deriving(Show)]
265 pub enum fixup_err {
266     unresolved_int_ty(IntVid),
267     unresolved_float_ty(FloatVid),
268     unresolved_ty(TyVid)
269 }
270
271 pub fn fixup_err_to_string(f: fixup_err) -> String {
272     match f {
273       unresolved_int_ty(_) => {
274           "cannot determine the type of this integer; add a suffix to \
275            specify the type explicitly".to_string()
276       }
277       unresolved_float_ty(_) => {
278           "cannot determine the type of this number; add a suffix to specify \
279            the type explicitly".to_string()
280       }
281       unresolved_ty(_) => "unconstrained type".to_string(),
282     }
283 }
284
285 pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
286                                 -> InferCtxt<'a, 'tcx> {
287     InferCtxt {
288         tcx: tcx,
289         type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
290         int_unification_table: RefCell::new(UnificationTable::new()),
291         float_unification_table: RefCell::new(UnificationTable::new()),
292         region_vars: RegionVarBindings::new(tcx),
293     }
294 }
295
296 pub fn common_supertype(cx: &InferCtxt,
297                         origin: TypeOrigin,
298                         a_is_expected: bool,
299                         a: ty::t,
300                         b: ty::t)
301                         -> ty::t
302 {
303     /*!
304      * Computes the least upper-bound of `a` and `b`. If this is
305      * not possible, reports an error and returns ty::err.
306      */
307
308     debug!("common_supertype({}, {})",
309            a.repr(cx.tcx), b.repr(cx.tcx));
310
311     let trace = TypeTrace {
312         origin: origin,
313         values: Types(expected_found(a_is_expected, a, b))
314     };
315
316     let result =
317         cx.commit_if_ok(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
318     match result {
319         Ok(t) => t,
320         Err(ref err) => {
321             cx.report_and_explain_type_error(trace, err);
322             ty::mk_err()
323         }
324     }
325 }
326
327 pub fn mk_subty(cx: &InferCtxt,
328                 a_is_expected: bool,
329                 origin: TypeOrigin,
330                 a: ty::t,
331                 b: ty::t)
332                 -> ures
333 {
334     debug!("mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
335     cx.commit_if_ok(|| {
336         cx.sub_types(a_is_expected, origin, a, b)
337     })
338 }
339
340 pub fn can_mk_subty(cx: &InferCtxt, a: ty::t, b: ty::t) -> ures {
341     debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
342     cx.probe(|| {
343         let trace = TypeTrace {
344             origin: Misc(codemap::DUMMY_SP),
345             values: Types(expected_found(true, a, b))
346         };
347         cx.sub(true, trace).tys(a, b).to_ures()
348     })
349 }
350
351 pub fn can_mk_eqty(cx: &InferCtxt, a: ty::t, b: ty::t) -> ures {
352     debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
353     cx.probe(|| {
354         let trace = TypeTrace {
355             origin: Misc(codemap::DUMMY_SP),
356             values: Types(expected_found(true, a, b))
357         };
358         cx.equate(true, trace).tys(a, b)
359     }).to_ures()
360 }
361
362 pub fn mk_subr(cx: &InferCtxt,
363                origin: SubregionOrigin,
364                a: ty::Region,
365                b: ty::Region) {
366     debug!("mk_subr({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
367     let snapshot = cx.region_vars.start_snapshot();
368     cx.region_vars.make_subregion(origin, a, b);
369     cx.region_vars.commit(snapshot);
370 }
371
372 pub fn verify_param_bound(cx: &InferCtxt,
373                           origin: SubregionOrigin,
374                           param_ty: ty::ParamTy,
375                           a: ty::Region,
376                           bs: Vec<ty::Region>) {
377     debug!("verify_param_bound({}, {} <: {})",
378            param_ty.repr(cx.tcx),
379            a.repr(cx.tcx),
380            bs.repr(cx.tcx));
381
382     cx.region_vars.verify_param_bound(origin, param_ty, a, bs);
383 }
384
385 pub fn mk_eqty(cx: &InferCtxt,
386                a_is_expected: bool,
387                origin: TypeOrigin,
388                a: ty::t,
389                b: ty::t)
390             -> ures
391 {
392     debug!("mk_eqty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
393     cx.commit_if_ok(
394         || cx.eq_types(a_is_expected, origin, a, b))
395 }
396
397 pub fn mk_sub_trait_refs(cx: &InferCtxt,
398                          a_is_expected: bool,
399                          origin: TypeOrigin,
400                          a: Rc<ty::TraitRef>,
401                          b: Rc<ty::TraitRef>)
402                          -> ures
403 {
404     debug!("mk_sub_trait_refs({} <: {})",
405            a.repr(cx.tcx), b.repr(cx.tcx));
406     cx.commit_if_ok(
407         || cx.sub_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
408 }
409
410 fn expected_found<T>(a_is_expected: bool,
411                      a: T,
412                      b: T)
413                      -> ty::expected_found<T>
414 {
415     if a_is_expected {
416         ty::expected_found {expected: a, found: b}
417     } else {
418         ty::expected_found {expected: b, found: a}
419     }
420 }
421
422 pub fn mk_coercety(cx: &InferCtxt,
423                    a_is_expected: bool,
424                    origin: TypeOrigin,
425                    a: ty::t,
426                    b: ty::t)
427                 -> CoerceResult {
428     debug!("mk_coercety({} -> {})", a.repr(cx.tcx), b.repr(cx.tcx));
429     indent(|| {
430         cx.commit_if_ok(|| {
431             let trace = TypeTrace {
432                 origin: origin,
433                 values: Types(expected_found(a_is_expected, a, b))
434             };
435             Coerce(cx.combine_fields(a_is_expected, trace)).tys(a, b)
436         })
437     })
438 }
439
440 // See comment on the type `resolve_state` below
441 pub fn resolve_type(cx: &InferCtxt,
442                     span: Option<Span>,
443                     a: ty::t,
444                     modes: uint)
445                     -> fres<ty::t> {
446     let mut resolver = resolver(cx, modes, span);
447     cx.commit_unconditionally(|| resolver.resolve_type_chk(a))
448 }
449
450 pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint)
451                       -> fres<ty::Region> {
452     let mut resolver = resolver(cx, modes, None);
453     resolver.resolve_region_chk(r)
454 }
455
456 trait then {
457     fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err>)
458         -> Result<T,ty::type_err>;
459 }
460
461 impl then for ures {
462     fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err>)
463         -> Result<T,ty::type_err> {
464         self.and_then(|_i| f())
465     }
466 }
467
468 trait ToUres {
469     fn to_ures(&self) -> ures;
470 }
471
472 impl<T> ToUres for cres<T> {
473     fn to_ures(&self) -> ures {
474         match *self {
475           Ok(ref _v) => Ok(()),
476           Err(ref e) => Err((*e))
477         }
478     }
479 }
480
481 trait CresCompare<T> {
482     fn compare(&self, t: T, f: || -> ty::type_err) -> cres<T>;
483 }
484
485 impl<T:Clone + PartialEq> CresCompare<T> for cres<T> {
486     fn compare(&self, t: T, f: || -> ty::type_err) -> cres<T> {
487         (*self).clone().and_then(|s| {
488             if s == t {
489                 (*self).clone()
490             } else {
491                 Err(f())
492             }
493         })
494     }
495 }
496
497 pub fn uok() -> ures {
498     Ok(())
499 }
500
501 pub struct CombinedSnapshot {
502     type_snapshot: type_variable::Snapshot,
503     int_snapshot: unify::Snapshot<ty::IntVid>,
504     float_snapshot: unify::Snapshot<ty::FloatVid>,
505     region_vars_snapshot: RegionSnapshot,
506 }
507
508 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
509     pub fn skolemize<T:TypeFoldable>(&self, t: T) -> T {
510         t.fold_with(&mut self.skolemizer())
511     }
512
513     pub fn skolemizer<'a>(&'a self) -> TypeSkolemizer<'a, 'tcx> {
514         skolemize::TypeSkolemizer::new(self)
515     }
516
517     pub fn combine_fields<'a>(&'a self, a_is_expected: bool, trace: TypeTrace)
518                               -> CombineFields<'a, 'tcx> {
519         CombineFields {infcx: self,
520                        a_is_expected: a_is_expected,
521                        trace: trace}
522     }
523
524     pub fn equate<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Equate<'a, 'tcx> {
525         Equate(self.combine_fields(a_is_expected, trace))
526     }
527
528     pub fn sub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Sub<'a, 'tcx> {
529         Sub(self.combine_fields(a_is_expected, trace))
530     }
531
532     pub fn lub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Lub<'a, 'tcx> {
533         Lub(self.combine_fields(a_is_expected, trace))
534     }
535
536     fn start_snapshot(&self) -> CombinedSnapshot {
537         CombinedSnapshot {
538             type_snapshot: self.type_variables.borrow_mut().snapshot(),
539             int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
540             float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
541             region_vars_snapshot: self.region_vars.start_snapshot(),
542         }
543     }
544
545     fn rollback_to(&self, snapshot: CombinedSnapshot) {
546         debug!("rollback!");
547         let CombinedSnapshot { type_snapshot,
548                                int_snapshot,
549                                float_snapshot,
550                                region_vars_snapshot } = snapshot;
551
552         self.type_variables
553             .borrow_mut()
554             .rollback_to(type_snapshot);
555         self.int_unification_table
556             .borrow_mut()
557             .rollback_to(int_snapshot);
558         self.float_unification_table
559             .borrow_mut()
560             .rollback_to(float_snapshot);
561         self.region_vars
562             .rollback_to(region_vars_snapshot);
563     }
564
565     fn commit_from(&self, snapshot: CombinedSnapshot) {
566         debug!("commit_from!");
567         let CombinedSnapshot { type_snapshot,
568                                int_snapshot,
569                                float_snapshot,
570                                region_vars_snapshot } = snapshot;
571
572         self.type_variables
573             .borrow_mut()
574             .commit(type_snapshot);
575         self.int_unification_table
576             .borrow_mut()
577             .commit(int_snapshot);
578         self.float_unification_table
579             .borrow_mut()
580             .commit(float_snapshot);
581         self.region_vars
582             .commit(region_vars_snapshot);
583     }
584
585     /// Execute `f` and commit the bindings
586     pub fn commit_unconditionally<R>(&self, f: || -> R) -> R {
587         debug!("commit()");
588         let snapshot = self.start_snapshot();
589         let r = f();
590         self.commit_from(snapshot);
591         r
592     }
593
594     /// Execute `f` and commit the bindings if successful
595     pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
596         self.commit_unconditionally(|| self.try(|| f()))
597     }
598
599     /// Execute `f`, unroll bindings on failure
600     pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
601         debug!("try()");
602         let snapshot = self.start_snapshot();
603         let r = f();
604         debug!("try() -- r.is_ok() = {}", r.is_ok());
605         match r {
606             Ok(_) => {
607                 self.commit_from(snapshot);
608             }
609             Err(_) => {
610                 self.rollback_to(snapshot);
611             }
612         }
613         r
614     }
615
616     /// Execute `f` then unroll any bindings it creates
617     pub fn probe<R>(&self, f: || -> R) -> R {
618         debug!("probe()");
619         let snapshot = self.start_snapshot();
620         let r = f();
621         self.rollback_to(snapshot);
622         r
623     }
624
625     pub fn add_given(&self,
626                      sub: ty::FreeRegion,
627                      sup: ty::RegionVid)
628     {
629         self.region_vars.add_given(sub, sup);
630     }
631
632     pub fn sub_types(&self,
633                      a_is_expected: bool,
634                      origin: TypeOrigin,
635                      a: ty::t,
636                      b: ty::t)
637                      -> ures
638     {
639         debug!("sub_types({} <: {})", a.repr(self.tcx), b.repr(self.tcx));
640         self.commit_if_ok(|| {
641             let trace = TypeTrace {
642                 origin: origin,
643                 values: Types(expected_found(a_is_expected, a, b))
644             };
645             self.sub(a_is_expected, trace).tys(a, b).to_ures()
646         })
647     }
648
649     pub fn eq_types(&self,
650                     a_is_expected: bool,
651                     origin: TypeOrigin,
652                     a: ty::t,
653                     b: ty::t)
654                     -> ures
655     {
656         self.commit_if_ok(|| {
657             let trace = TypeTrace {
658                 origin: origin,
659                 values: Types(expected_found(a_is_expected, a, b))
660             };
661             self.equate(a_is_expected, trace).tys(a, b).to_ures()
662         })
663     }
664
665     pub fn sub_trait_refs(&self,
666                           a_is_expected: bool,
667                           origin: TypeOrigin,
668                           a: Rc<ty::TraitRef>,
669                           b: Rc<ty::TraitRef>)
670                           -> ures
671     {
672         debug!("sub_trait_refs({} <: {})",
673                a.repr(self.tcx),
674                b.repr(self.tcx));
675         self.commit_if_ok(|| {
676             let trace = TypeTrace {
677                 origin: origin,
678                 values: TraitRefs(expected_found(a_is_expected,
679                                                  a.clone(), b.clone()))
680             };
681             self.sub(a_is_expected, trace).trait_refs(&*a, &*b).to_ures()
682         })
683     }
684 }
685
686 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
687     pub fn next_ty_var_id(&self) -> TyVid {
688         self.type_variables
689             .borrow_mut()
690             .new_var()
691     }
692
693     pub fn next_ty_var(&self) -> ty::t {
694         ty::mk_var(self.tcx, self.next_ty_var_id())
695     }
696
697     pub fn next_ty_vars(&self, n: uint) -> Vec<ty::t> {
698         Vec::from_fn(n, |_i| self.next_ty_var())
699     }
700
701     pub fn next_int_var_id(&self) -> IntVid {
702         self.int_unification_table
703             .borrow_mut()
704             .new_key(None)
705     }
706
707     pub fn next_float_var_id(&self) -> FloatVid {
708         self.float_unification_table
709             .borrow_mut()
710             .new_key(None)
711     }
712
713     pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
714         ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
715     }
716
717     pub fn region_vars_for_defs(&self,
718                                 span: Span,
719                                 defs: &[ty::RegionParameterDef])
720                                 -> Vec<ty::Region> {
721         defs.iter()
722             .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
723             .collect()
724     }
725
726     pub fn fresh_substs_for_generics(&self,
727                                      span: Span,
728                                      generics: &ty::Generics)
729                                      -> subst::Substs
730     {
731         /*!
732          * Given a set of generics defined on a type or impl, returns
733          * a substitution mapping each type/region parameter to a
734          * fresh inference variable.
735          */
736
737         let type_params =
738             generics.types.map(
739                 |_| self.next_ty_var());
740         let region_params =
741             generics.regions.map(
742                 |d| self.next_region_var(EarlyBoundRegion(span, d.name)));
743         subst::Substs::new(type_params, region_params)
744     }
745
746     pub fn fresh_substs_for_trait(&self,
747                                   span: Span,
748                                   generics: &ty::Generics,
749                                   self_ty: ty::t)
750                                   -> subst::Substs
751     {
752         /*!
753          * Given a set of generics defined on a trait, returns a
754          * substitution mapping each output type/region parameter to a
755          * fresh inference variable, and mapping the self type to
756          * `self_ty`.
757          */
758
759         assert!(generics.types.len(subst::SelfSpace) == 1);
760         assert!(generics.types.len(subst::FnSpace) == 0);
761         assert!(generics.regions.len(subst::SelfSpace) == 0);
762         assert!(generics.regions.len(subst::FnSpace) == 0);
763
764         let type_parameter_count = generics.types.len(subst::TypeSpace);
765         let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
766         let regions = self.region_vars_for_defs(span, region_param_defs);
767         let type_parameters = self.next_ty_vars(type_parameter_count);
768         subst::Substs::new_trait(type_parameters, regions, self_ty)
769     }
770
771     pub fn fresh_bound_region(&self, binder_id: ast::NodeId) -> ty::Region {
772         self.region_vars.new_bound(binder_id)
773     }
774
775     pub fn resolve_regions_and_report_errors(&self) {
776         let errors = self.region_vars.resolve_regions();
777         self.report_region_errors(&errors); // see error_reporting.rs
778     }
779
780     pub fn ty_to_string(&self, t: ty::t) -> String {
781         ty_to_string(self.tcx,
782                   self.resolve_type_vars_if_possible(t))
783     }
784
785     pub fn tys_to_string(&self, ts: &[ty::t]) -> String {
786         let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
787         format!("({})", tstrs.connect(", "))
788     }
789
790     pub fn trait_ref_to_string(&self, t: &ty::TraitRef) -> String {
791         let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
792         trait_ref_to_string(self.tcx, &t)
793     }
794
795     pub fn contains_unbound_type_variables(&self, typ: ty::t) -> ty::t {
796         match resolve_type(self,
797                            None,
798                            typ, resolve_nested_tvar | resolve_ivar) {
799           Ok(new_type) => new_type,
800           Err(_) => typ
801         }
802     }
803
804     pub fn shallow_resolve(&self, typ: ty::t) -> ty::t {
805         match ty::get(typ).sty {
806             ty::ty_infer(ty::TyVar(v)) => {
807                 self.type_variables.borrow()
808                     .probe(v)
809                     .unwrap_or(typ)
810             }
811
812             ty::ty_infer(ty::IntVar(v)) => {
813                 self.probe_var(v)
814                     .unwrap_or(typ)
815             }
816
817             ty::ty_infer(ty::FloatVar(v)) => {
818                 self.probe_var(v)
819                     .unwrap_or(typ)
820             }
821
822             _ => {
823                 typ
824             }
825         }
826     }
827
828     pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t {
829         match resolve_type(self,
830                            None,
831                            typ, resolve_nested_tvar | resolve_ivar) {
832           Ok(new_type) => new_type,
833           Err(_) => typ
834         }
835     }
836
837     pub fn resolve_type_vars_in_trait_ref_if_possible(&self,
838                                                       trait_ref: &ty::TraitRef)
839                                                       -> ty::TraitRef {
840         // make up a dummy type just to reuse/abuse the resolve machinery
841         let dummy0 = ty::mk_trait(self.tcx,
842                                   trait_ref.def_id,
843                                   trait_ref.substs.clone(),
844                                   ty::region_existential_bound(ty::ReStatic));
845         let dummy1 = self.resolve_type_vars_if_possible(dummy0);
846         match ty::get(dummy1).sty {
847             ty::ty_trait(box ty::TyTrait { ref def_id, ref substs, .. }) => {
848                 ty::TraitRef {
849                     def_id: *def_id,
850                     substs: (*substs).clone(),
851                 }
852             }
853             _ => {
854                 self.tcx.sess.bug(
855                     format!("resolve_type_vars_if_possible() yielded {} \
856                              when supplied with {}",
857                             self.ty_to_string(dummy0),
858                             self.ty_to_string(dummy1)).as_slice());
859             }
860         }
861     }
862
863     // [Note-Type-error-reporting]
864     // An invariant is that anytime the expected or actual type is ty_err (the special
865     // error type, meaning that an error occurred when typechecking this expression),
866     // this is a derived error. The error cascaded from another error (that was already
867     // reported), so it's not useful to display it to the user.
868     // The following four methods -- type_error_message_str, type_error_message_str_with_expected,
869     // type_error_message, and report_mismatched_types -- implement this logic.
870     // They check if either the actual or expected type is ty_err, and don't print the error
871     // in this case. The typechecker should only ever report type errors involving mismatched
872     // types using one of these four methods, and should not call span_err directly for such
873     // errors.
874     pub fn type_error_message_str(&self,
875                                   sp: Span,
876                                   mk_msg: |Option<String>, String| -> String,
877                                   actual_ty: String,
878                                   err: Option<&ty::type_err>) {
879         self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
880     }
881
882     pub fn type_error_message_str_with_expected(&self,
883                                                 sp: Span,
884                                                 mk_msg: |Option<String>,
885                                                          String|
886                                                          -> String,
887                                                 expected_ty: Option<ty::t>,
888                                                 actual_ty: String,
889                                                 err: Option<&ty::type_err>) {
890         debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
891
892         let error_str = err.map_or("".to_string(), |t_err| {
893             format!(" ({})", ty::type_err_to_str(self.tcx, t_err))
894         });
895         let resolved_expected = expected_ty.map(|e_ty| {
896             self.resolve_type_vars_if_possible(e_ty)
897         });
898         if !resolved_expected.map_or(false, |e| { ty::type_is_error(e) }) {
899             match resolved_expected {
900                 None => {
901                     self.tcx
902                         .sess
903                         .span_err(sp,
904                                   format!("{}{}",
905                                           mk_msg(None, actual_ty),
906                                           error_str).as_slice())
907                 }
908                 Some(e) => {
909                     self.tcx.sess.span_err(sp,
910                         format!("{}{}",
911                                 mk_msg(Some(self.ty_to_string(e)), actual_ty),
912                                 error_str).as_slice());
913                 }
914             }
915             for err in err.iter() {
916                 ty::note_and_explain_type_err(self.tcx, *err)
917             }
918         }
919     }
920
921     pub fn type_error_message(&self,
922                               sp: Span,
923                               mk_msg: |String| -> String,
924                               actual_ty: ty::t,
925                               err: Option<&ty::type_err>) {
926         let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
927
928         // Don't report an error if actual type is ty_err.
929         if ty::type_is_error(actual_ty) {
930             return;
931         }
932
933         self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
934     }
935
936     pub fn report_mismatched_types(&self,
937                                    sp: Span,
938                                    e: ty::t,
939                                    a: ty::t,
940                                    err: &ty::type_err) {
941         let resolved_expected =
942             self.resolve_type_vars_if_possible(e);
943         let mk_msg = match ty::get(resolved_expected).sty {
944             // Don't report an error if expected is ty_err
945             ty::ty_err => return,
946             _ => {
947                 // if I leave out : String, it infers &str and complains
948                 |actual: String| {
949                     format!("mismatched types: expected `{}`, found `{}`",
950                             self.ty_to_string(resolved_expected),
951                             actual)
952                 }
953             }
954         };
955         self.type_error_message(sp, mk_msg, a, Some(err));
956     }
957
958     pub fn replace_late_bound_regions_with_fresh_regions(&self,
959                                                          trace: TypeTrace,
960                                                          fsig: &ty::FnSig)
961                                                     -> (ty::FnSig,
962                                                         HashMap<ty::BoundRegion,
963                                                                 ty::Region>) {
964         let (map, fn_sig) =
965             replace_late_bound_regions_in_fn_sig(self.tcx, fsig, |br| {
966                 let rvar = self.next_region_var(
967                     BoundRegionInFnType(trace.origin.span(), br));
968                 debug!("Bound region {} maps to {:?}",
969                        bound_region_to_string(self.tcx, "", false, br),
970                        rvar);
971                 rvar
972             });
973         (fn_sig, map)
974     }
975 }
976
977 pub fn fold_regions_in_sig(tcx: &ty::ctxt,
978                            fn_sig: &ty::FnSig,
979                            fldr: |r: ty::Region| -> ty::Region)
980                            -> ty::FnSig {
981     ty_fold::RegionFolder::regions(tcx, fldr).fold_sig(fn_sig)
982 }
983
984 impl TypeTrace {
985     pub fn span(&self) -> Span {
986         self.origin.span()
987     }
988 }
989
990 impl Repr for TypeTrace {
991     fn repr(&self, tcx: &ty::ctxt) -> String {
992         format!("TypeTrace({})", self.origin.repr(tcx))
993     }
994 }
995
996 impl TypeOrigin {
997     pub fn span(&self) -> Span {
998         match *self {
999             MethodCompatCheck(span) => span,
1000             ExprAssignable(span) => span,
1001             Misc(span) => span,
1002             RelateTraitRefs(span) => span,
1003             RelateSelfType(span) => span,
1004             RelateOutputImplTypes(span) => span,
1005             MatchExpressionArm(match_span, _) => match_span,
1006             IfExpression(span) => span,
1007             IfExpressionWithNoElse(span) => span
1008         }
1009     }
1010 }
1011
1012 impl Repr for TypeOrigin {
1013     fn repr(&self, tcx: &ty::ctxt) -> String {
1014         match *self {
1015             MethodCompatCheck(a) => {
1016                 format!("MethodCompatCheck({})", a.repr(tcx))
1017             }
1018             ExprAssignable(a) => {
1019                 format!("ExprAssignable({})", a.repr(tcx))
1020             }
1021             Misc(a) => format!("Misc({})", a.repr(tcx)),
1022             RelateTraitRefs(a) => {
1023                 format!("RelateTraitRefs({})", a.repr(tcx))
1024             }
1025             RelateSelfType(a) => {
1026                 format!("RelateSelfType({})", a.repr(tcx))
1027             }
1028             RelateOutputImplTypes(a) => {
1029                 format!("RelateOutputImplTypes({})", a.repr(tcx))
1030             }
1031             MatchExpressionArm(a, b) => {
1032                 format!("MatchExpressionArm({}, {})", a.repr(tcx), b.repr(tcx))
1033             }
1034             IfExpression(a) => {
1035                 format!("IfExpression({})", a.repr(tcx))
1036             }
1037             IfExpressionWithNoElse(a) => {
1038                 format!("IfExpressionWithNoElse({})", a.repr(tcx))
1039             }
1040         }
1041     }
1042 }
1043
1044 impl SubregionOrigin {
1045     pub fn span(&self) -> Span {
1046         match *self {
1047             Subtype(ref a) => a.span(),
1048             InfStackClosure(a) => a,
1049             InvokeClosure(a) => a,
1050             DerefPointer(a) => a,
1051             FreeVariable(a, _) => a,
1052             ProcCapture(a, _) => a,
1053             IndexSlice(a) => a,
1054             RelateObjectBound(a) => a,
1055             RelateProcBound(a, _, _) => a,
1056             RelateParamBound(a, _, _) => a,
1057             RelateRegionParamBound(a) => a,
1058             RelateDefaultParamBound(a, _) => a,
1059             Reborrow(a) => a,
1060             ReborrowUpvar(a, _) => a,
1061             ReferenceOutlivesReferent(_, a) => a,
1062             ExprTypeIsNotInScope(_, a) => a,
1063             BindingTypeIsNotValidAtDecl(a) => a,
1064             CallRcvr(a) => a,
1065             CallArg(a) => a,
1066             CallReturn(a) => a,
1067             AddrOf(a) => a,
1068             AutoBorrow(a) => a,
1069         }
1070     }
1071 }
1072
1073 impl Repr for SubregionOrigin {
1074     fn repr(&self, tcx: &ty::ctxt) -> String {
1075         match *self {
1076             Subtype(ref a) => {
1077                 format!("Subtype({})", a.repr(tcx))
1078             }
1079             InfStackClosure(a) => {
1080                 format!("InfStackClosure({})", a.repr(tcx))
1081             }
1082             InvokeClosure(a) => {
1083                 format!("InvokeClosure({})", a.repr(tcx))
1084             }
1085             DerefPointer(a) => {
1086                 format!("DerefPointer({})", a.repr(tcx))
1087             }
1088             FreeVariable(a, b) => {
1089                 format!("FreeVariable({}, {})", a.repr(tcx), b)
1090             }
1091             ProcCapture(a, b) => {
1092                 format!("ProcCapture({}, {})", a.repr(tcx), b)
1093             }
1094             IndexSlice(a) => {
1095                 format!("IndexSlice({})", a.repr(tcx))
1096             }
1097             RelateObjectBound(a) => {
1098                 format!("RelateObjectBound({})", a.repr(tcx))
1099             }
1100             RelateProcBound(a, b, c) => {
1101                 format!("RelateProcBound({},{},{})",
1102                         a.repr(tcx),
1103                         b,
1104                         c.repr(tcx))
1105             }
1106             RelateParamBound(a, b, c) => {
1107                 format!("RelateParamBound({},{},{})",
1108                         a.repr(tcx),
1109                         b.repr(tcx),
1110                         c.repr(tcx))
1111             }
1112             RelateRegionParamBound(a) => {
1113                 format!("RelateRegionParamBound({})",
1114                         a.repr(tcx))
1115             }
1116             RelateDefaultParamBound(a, b) => {
1117                 format!("RelateDefaultParamBound({},{})",
1118                         a.repr(tcx),
1119                         b.repr(tcx))
1120             }
1121             Reborrow(a) => format!("Reborrow({})", a.repr(tcx)),
1122             ReborrowUpvar(a, b) => {
1123                 format!("ReborrowUpvar({},{:?})", a.repr(tcx), b)
1124             }
1125             ReferenceOutlivesReferent(_, a) => {
1126                 format!("ReferenceOutlivesReferent({})", a.repr(tcx))
1127             }
1128             ExprTypeIsNotInScope(a, b) => {
1129                 format!("ExprTypeIsNotInScope({}, {})",
1130                         a.repr(tcx),
1131                         b.repr(tcx))
1132             }
1133             BindingTypeIsNotValidAtDecl(a) => {
1134                 format!("BindingTypeIsNotValidAtDecl({})", a.repr(tcx))
1135             }
1136             CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
1137             CallArg(a) => format!("CallArg({})", a.repr(tcx)),
1138             CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
1139             AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
1140             AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
1141         }
1142     }
1143 }
1144
1145 impl RegionVariableOrigin {
1146     pub fn span(&self) -> Span {
1147         match *self {
1148             MiscVariable(a) => a,
1149             PatternRegion(a) => a,
1150             AddrOfRegion(a) => a,
1151             AddrOfSlice(a) => a,
1152             Autoref(a) => a,
1153             Coercion(ref a) => a.span(),
1154             EarlyBoundRegion(a, _) => a,
1155             LateBoundRegion(a, _) => a,
1156             BoundRegionInFnType(a, _) => a,
1157             BoundRegionInCoherence(_) => codemap::DUMMY_SP,
1158             UpvarRegion(_, a) => a
1159         }
1160     }
1161 }
1162
1163 impl Repr for RegionVariableOrigin {
1164     fn repr(&self, tcx: &ty::ctxt) -> String {
1165         match *self {
1166             MiscVariable(a) => {
1167                 format!("MiscVariable({})", a.repr(tcx))
1168             }
1169             PatternRegion(a) => {
1170                 format!("PatternRegion({})", a.repr(tcx))
1171             }
1172             AddrOfRegion(a) => {
1173                 format!("AddrOfRegion({})", a.repr(tcx))
1174             }
1175             AddrOfSlice(a) => format!("AddrOfSlice({})", a.repr(tcx)),
1176             Autoref(a) => format!("Autoref({})", a.repr(tcx)),
1177             Coercion(ref a) => format!("Coercion({})", a.repr(tcx)),
1178             EarlyBoundRegion(a, b) => {
1179                 format!("EarlyBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
1180             }
1181             LateBoundRegion(a, b) => {
1182                 format!("LateBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
1183             }
1184             BoundRegionInFnType(a, b) => {
1185                 format!("bound_regionInFnType({},{})", a.repr(tcx),
1186                 b.repr(tcx))
1187             }
1188             BoundRegionInCoherence(a) => {
1189                 format!("bound_regionInCoherence({})", a.repr(tcx))
1190             }
1191             UpvarRegion(a, b) => {
1192                 format!("UpvarRegion({}, {})", a.repr(tcx), b.repr(tcx))
1193             }
1194         }
1195     }
1196 }