]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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 | ||
c34b1796 | 11 | use super::combine::CombineFields; |
1a4d82fc | 12 | use super::higher_ranked::HigherRankedRelations; |
c34b1796 AL |
13 | use super::InferCtxt; |
14 | use super::lattice::{self, LatticeDir}; | |
85aaf69f | 15 | use super::Subtype; |
1a4d82fc | 16 | |
1a4d82fc | 17 | use middle::ty::{self, Ty}; |
e9174d1e | 18 | use middle::ty::relate::{Relate, RelateResult, TypeRelation}; |
1a4d82fc JJ |
19 | |
20 | /// "Greatest lower bound" (common subtype) | |
c34b1796 AL |
21 | pub struct Glb<'a, 'tcx: 'a> { |
22 | fields: CombineFields<'a, 'tcx> | |
1a4d82fc JJ |
23 | } |
24 | ||
c34b1796 AL |
25 | impl<'a, 'tcx> Glb<'a, 'tcx> { |
26 | pub fn new(fields: CombineFields<'a, 'tcx>) -> Glb<'a, 'tcx> { | |
27 | Glb { fields: fields } | |
85aaf69f | 28 | } |
c34b1796 | 29 | } |
85aaf69f | 30 | |
c34b1796 AL |
31 | impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> { |
32 | fn tag(&self) -> &'static str { "Glb" } | |
1a4d82fc | 33 | |
c34b1796 | 34 | fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() } |
1a4d82fc | 35 | |
c34b1796 | 36 | fn a_is_expected(&self) -> bool { self.fields.a_is_expected } |
1a4d82fc | 37 | |
c34b1796 AL |
38 | fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self, |
39 | variance: ty::Variance, | |
40 | a: &T, | |
41 | b: &T) | |
42 | -> RelateResult<'tcx, T> | |
43 | { | |
44 | match variance { | |
45 | ty::Invariant => self.fields.equate().relate(a, b), | |
46 | ty::Covariant => self.relate(a, b), | |
47 | ty::Bivariant => self.fields.bivariate().relate(a, b), | |
48 | ty::Contravariant => self.fields.lub().relate(a, b), | |
1a4d82fc JJ |
49 | } |
50 | } | |
51 | ||
c34b1796 AL |
52 | fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { |
53 | lattice::super_lattice_tys(self, a, b) | |
1a4d82fc JJ |
54 | } |
55 | ||
c34b1796 | 56 | fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> { |
62682a34 | 57 | debug!("{}.regions({:?}, {:?})", |
1a4d82fc | 58 | self.tag(), |
62682a34 SL |
59 | a, |
60 | b); | |
1a4d82fc | 61 | |
c34b1796 AL |
62 | let origin = Subtype(self.fields.trace.clone()); |
63 | Ok(self.fields.infcx.region_vars.glb_regions(origin, a, b)) | |
1a4d82fc JJ |
64 | } |
65 | ||
c34b1796 AL |
66 | fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>) |
67 | -> RelateResult<'tcx, ty::Binder<T>> | |
68 | where T: Relate<'a, 'tcx> | |
69 | { | |
70 | self.fields.higher_ranked_glb(a, b) | |
1a4d82fc | 71 | } |
c34b1796 | 72 | } |
1a4d82fc | 73 | |
c34b1796 AL |
74 | impl<'a, 'tcx> LatticeDir<'a,'tcx> for Glb<'a, 'tcx> { |
75 | fn infcx(&self) -> &'a InferCtxt<'a,'tcx> { | |
76 | self.fields.infcx | |
77 | } | |
78 | ||
79 | fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> { | |
80 | let mut sub = self.fields.sub(); | |
81 | try!(sub.relate(&v, &a)); | |
82 | try!(sub.relate(&v, &b)); | |
83 | Ok(()) | |
1a4d82fc JJ |
84 | } |
85 | } |