1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use super::*;
use super::combine::*;
use super::glb::Glb;
use super::lub::Lub;
use middle::ty::{TyVar};
use middle::ty::{mod, Ty};
use util::ppaux::Repr;
pub trait LatticeDir<'tcx> {
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()>;
}
impl<'a, 'tcx> LatticeDir<'tcx> for Lub<'a, 'tcx> {
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()> {
let sub = self.sub();
try!(sub.tys(a, v));
try!(sub.tys(b, v));
Ok(())
}
}
impl<'a, 'tcx> LatticeDir<'tcx> for Glb<'a, 'tcx> {
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()> {
let sub = self.sub();
try!(sub.tys(v, a));
try!(sub.tys(v, b));
Ok(())
}
}
pub fn super_lattice_tys<'tcx, L:LatticeDir<'tcx>+Combine<'tcx>>(this: &L,
a: Ty<'tcx>,
b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>>
{
debug!("{}.lattice_tys({}, {})",
this.tag(),
a.repr(this.infcx().tcx),
b.repr(this.infcx().tcx));
if a == b {
return Ok(a);
}
let infcx = this.infcx();
let a = infcx.type_variables.borrow().replace_if_possible(a);
let b = infcx.type_variables.borrow().replace_if_possible(b);
match (&a.sty, &b.sty) {
(&ty::ty_infer(TyVar(..)), &ty::ty_infer(TyVar(..)))
if infcx.type_var_diverges(a) && infcx.type_var_diverges(b) => {
let v = infcx.next_diverging_ty_var();
try!(this.relate_bound(v, a, b));
Ok(v)
}
(&ty::ty_infer(TyVar(..)), _) |
(_, &ty::ty_infer(TyVar(..))) => {
let v = infcx.next_ty_var();
try!(this.relate_bound(v, a, b));
Ok(v)
}
_ => {
super_tys(this, a, b)
}
}
}