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 use super::combine
::{self, CombineFields}
;
12 use super::higher_ranked
::HigherRankedRelations
;
14 use super::type_variable
::{SubtypeOf, SupertypeOf}
;
16 use middle
::ty
::{self, Ty}
;
17 use middle
::ty
::TyVar
;
18 use middle
::ty_relate
::{Relate, RelateResult, TypeRelation}
;
19 use util
::ppaux
::{Repr}
;
21 /// "Greatest lower bound" (common subtype)
22 pub struct Sub
<'a
, 'tcx
: 'a
> {
23 fields
: CombineFields
<'a
, 'tcx
>
26 impl<'a
, 'tcx
> Sub
<'a
, 'tcx
> {
27 pub fn new(f
: CombineFields
<'a
, 'tcx
>) -> Sub
<'a
, 'tcx
> {
32 impl<'a
, 'tcx
> TypeRelation
<'a
, 'tcx
> for Sub
<'a
, 'tcx
> {
33 fn tag(&self) -> &'
static str { "Sub" }
34 fn tcx(&self) -> &'a ty
::ctxt
<'tcx
> { self.fields.infcx.tcx }
35 fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
37 fn relate_with_variance
<T
:Relate
<'a
,'tcx
>>(&mut self,
38 variance
: ty
::Variance
,
41 -> RelateResult
<'tcx
, T
>
44 ty
::Invariant
=> self.fields
.equate().relate(a
, b
),
45 ty
::Covariant
=> self.relate(a
, b
),
46 ty
::Bivariant
=> self.fields
.bivariate().relate(a
, b
),
47 ty
::Contravariant
=> self.fields
.switch_expected().sub().relate(b
, a
),
51 fn tys(&mut self, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, Ty
<'tcx
>> {
52 debug
!("{}.tys({}, {})", self.tag(), a
.repr(self.tcx()), b
.repr(self.tcx()));
54 if a
== b { return Ok(a); }
56 let infcx
= self.fields
.infcx
;
57 let a
= infcx
.type_variables
.borrow().replace_if_possible(a
);
58 let b
= infcx
.type_variables
.borrow().replace_if_possible(b
);
59 match (&a
.sty
, &b
.sty
) {
60 (&ty
::ty_infer(TyVar(a_id
)), &ty
::ty_infer(TyVar(b_id
))) => {
63 .relate_vars(a_id
, SubtypeOf
, b_id
);
66 (&ty
::ty_infer(TyVar(a_id
)), _
) => {
69 .instantiate(b
, SupertypeOf
, a_id
));
72 (_
, &ty
::ty_infer(TyVar(b_id
))) => {
73 try
!(self.fields
.instantiate(a
, SubtypeOf
, b_id
));
77 (&ty
::ty_err
, _
) | (_
, &ty
::ty_err
) => {
78 Ok(self.tcx().types
.err
)
82 combine
::super_combine_tys(self.fields
.infcx
, self, a
, b
)
87 fn regions(&mut self, a
: ty
::Region
, b
: ty
::Region
) -> RelateResult
<'tcx
, ty
::Region
> {
88 debug
!("{}.regions({}, {})",
92 let origin
= Subtype(self.fields
.trace
.clone());
93 self.fields
.infcx
.region_vars
.make_subregion(origin
, a
, b
);
97 fn binders
<T
>(&mut self, a
: &ty
::Binder
<T
>, b
: &ty
::Binder
<T
>)
98 -> RelateResult
<'tcx
, ty
::Binder
<T
>>
99 where T
: Relate
<'a
,'tcx
>
101 self.fields
.higher_ranked_sub(a
, b
)