]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/infer/lattice.rs
doc: remove incomplete sentence
[rust.git] / src / librustc / middle / infer / lattice.rs
1 // Copyright 2012 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 //! # Lattice Variables
12 //!
13 //! This file contains generic code for operating on inference variables
14 //! that are characterized by an upper- and lower-bound.  The logic and
15 //! reasoning is explained in detail in the large comment in `infer.rs`.
16 //!
17 //! The code in here is defined quite generically so that it can be
18 //! applied both to type variables, which represent types being inferred,
19 //! and fn variables, which represent function types being inferred.
20 //! It may eventually be applied to their types as well, who knows.
21 //! In some cases, the functions are also generic with respect to the
22 //! operation on the lattice (GLB vs LUB).
23 //!
24 //! Although all the functions are generic, we generally write the
25 //! comments in a way that is specific to type variables and the LUB
26 //! operation.  It's just easier that way.
27 //!
28 //! In general all of the functions are defined parametrically
29 //! over a `LatticeValue`, which is a value defined with respect to
30 //! a lattice.
31
32 use super::*;
33 use super::combine::*;
34 use super::glb::Glb;
35 use super::lub::Lub;
36
37 use middle::ty::{TyVar};
38 use middle::ty::{mod, Ty};
39 use util::ppaux::Repr;
40
41 pub trait LatticeDir<'tcx> {
42     // Relates the type `v` to `a` and `b` such that `v` represents
43     // the LUB/GLB of `a` and `b` as appropriate.
44     fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()>;
45 }
46
47 impl<'a, 'tcx> LatticeDir<'tcx> for Lub<'a, 'tcx> {
48     fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()> {
49         let sub = self.sub();
50         try!(sub.tys(a, v));
51         try!(sub.tys(b, v));
52         Ok(())
53     }
54 }
55
56 impl<'a, 'tcx> LatticeDir<'tcx> for Glb<'a, 'tcx> {
57     fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()> {
58         let sub = self.sub();
59         try!(sub.tys(v, a));
60         try!(sub.tys(v, b));
61         Ok(())
62     }
63 }
64
65 pub fn super_lattice_tys<'tcx, L:LatticeDir<'tcx>+Combine<'tcx>>(this: &L,
66                                                                  a: Ty<'tcx>,
67                                                                  b: Ty<'tcx>)
68                                                                  -> cres<'tcx, Ty<'tcx>>
69 {
70     debug!("{}.lattice_tys({}, {})",
71            this.tag(),
72            a.repr(this.infcx().tcx),
73            b.repr(this.infcx().tcx));
74
75     if a == b {
76         return Ok(a);
77     }
78
79     let infcx = this.infcx();
80     let a = infcx.type_variables.borrow().replace_if_possible(a);
81     let b = infcx.type_variables.borrow().replace_if_possible(b);
82     match (&a.sty, &b.sty) {
83         (&ty::ty_infer(TyVar(..)), &ty::ty_infer(TyVar(..)))
84             if infcx.type_var_diverges(a) && infcx.type_var_diverges(b) => {
85             let v = infcx.next_diverging_ty_var();
86             try!(this.relate_bound(v, a, b));
87             Ok(v)
88         }
89
90         (&ty::ty_infer(TyVar(..)), _) |
91         (_, &ty::ty_infer(TyVar(..))) => {
92             let v = infcx.next_ty_var();
93             try!(this.relate_bound(v, a, b));
94             Ok(v)
95         }
96
97         _ => {
98             super_tys(this, a, b)
99         }
100     }
101 }