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.
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.
11 //! # Lattice Variables
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`.
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).
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.
28 //! In general all of the functions are defined parametrically
29 //! over a `LatticeValue`, which is a value defined with respect to
36 use ty
::relate
::{RelateResult, TypeRelation}
;
38 pub trait LatticeDir
<'f
, 'gcx
: 'f
+'tcx
, 'tcx
: 'f
> : TypeRelation
<'f
, 'gcx
, 'tcx
> {
39 fn infcx(&self) -> &'f InferCtxt
<'f
, 'gcx
, 'tcx
>;
41 // Relates the type `v` to `a` and `b` such that `v` represents
42 // the LUB/GLB of `a` and `b` as appropriate.
43 fn relate_bound(&self, v
: Ty
<'tcx
>, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, ()>;
46 pub fn super_lattice_tys
<'a
, 'gcx
, 'tcx
, L
>(this
: &mut L
,
49 -> RelateResult
<'tcx
, Ty
<'tcx
>>
50 where L
: LatticeDir
<'a
, 'gcx
, 'tcx
>, 'gcx
: 'a
+'tcx
, 'tcx
: 'a
52 debug
!("{}.lattice_tys({:?}, {:?})",
61 let infcx
= this
.infcx();
62 let a
= infcx
.type_variables
.borrow_mut().replace_if_possible(a
);
63 let b
= infcx
.type_variables
.borrow_mut().replace_if_possible(b
);
64 match (&a
.sty
, &b
.sty
) {
65 (&ty
::TyInfer(TyVar(..)), &ty
::TyInfer(TyVar(..)))
66 if infcx
.type_var_diverges(a
) && infcx
.type_var_diverges(b
) => {
67 let v
= infcx
.next_diverging_ty_var();
68 this
.relate_bound(v
, a
, b
)?
;
72 (&ty
::TyInfer(TyVar(..)), _
) |
73 (_
, &ty
::TyInfer(TyVar(..))) => {
74 let v
= infcx
.next_ty_var();
75 this
.relate_bound(v
, a
, b
)?
;
80 infcx
.super_combine_tys(this
, a
, b
)