1 use super::combine
::CombineFields
;
3 use super::lattice
::{self, LatticeDir}
;
6 use crate::traits
::ObligationCause
;
7 use crate::ty
::{self, Ty, TyCtxt}
;
8 use crate::ty
::relate
::{Relate, RelateResult, TypeRelation}
;
10 /// "Greatest lower bound" (common subtype)
11 pub struct Glb
<'combine
, 'infcx
: 'combine
, 'gcx
: 'infcx
+'tcx
, 'tcx
: 'infcx
> {
12 fields
: &'combine
mut CombineFields
<'infcx
, 'gcx
, 'tcx
>,
16 impl<'combine
, 'infcx
, 'gcx
, 'tcx
> Glb
<'combine
, 'infcx
, 'gcx
, 'tcx
> {
17 pub fn new(fields
: &'combine
mut CombineFields
<'infcx
, 'gcx
, 'tcx
>, a_is_expected
: bool
)
18 -> Glb
<'combine
, 'infcx
, 'gcx
, 'tcx
>
20 Glb { fields: fields, a_is_expected: a_is_expected }
24 impl<'combine
, 'infcx
, 'gcx
, 'tcx
> TypeRelation
<'infcx
, 'gcx
, 'tcx
>
25 for Glb
<'combine
, 'infcx
, 'gcx
, 'tcx
>
27 fn tag(&self) -> &'
static str { "Glb" }
29 fn tcx(&self) -> TyCtxt
<'infcx
, 'gcx
, 'tcx
> { self.fields.tcx() }
31 fn a_is_expected(&self) -> bool { self.a_is_expected }
33 fn relate_with_variance
<T
: Relate
<'tcx
>>(&mut self,
34 variance
: ty
::Variance
,
37 -> RelateResult
<'tcx
, T
>
40 ty
::Invariant
=> self.fields
.equate(self.a_is_expected
).relate(a
, b
),
41 ty
::Covariant
=> self.relate(a
, b
),
42 // FIXME(#41044) -- not correct, need test
43 ty
::Bivariant
=> Ok(a
.clone()),
44 ty
::Contravariant
=> self.fields
.lub(self.a_is_expected
).relate(a
, b
),
48 fn tys(&mut self, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, Ty
<'tcx
>> {
49 lattice
::super_lattice_tys(self, a
, b
)
52 fn regions(&mut self, a
: ty
::Region
<'tcx
>, b
: ty
::Region
<'tcx
>)
53 -> RelateResult
<'tcx
, ty
::Region
<'tcx
>> {
54 debug
!("{}.regions({:?}, {:?})",
59 let origin
= Subtype(self.fields
.trace
.clone());
60 Ok(self.fields
.infcx
.borrow_region_constraints().glb_regions(self.tcx(), origin
, a
, b
))
63 fn binders
<T
>(&mut self, a
: &ty
::Binder
<T
>, b
: &ty
::Binder
<T
>)
64 -> RelateResult
<'tcx
, ty
::Binder
<T
>>
67 debug
!("binders(a={:?}, b={:?})", a
, b
);
69 // When higher-ranked types are involved, computing the LUB is
70 // very challenging, switch to invariance. This is obviously
71 // overly conservative but works ok in practice.
72 self.relate_with_variance(ty
::Variance
::Invariant
, a
, b
)?
;
77 impl<'combine
, 'infcx
, 'gcx
, 'tcx
> LatticeDir
<'infcx
, 'gcx
, 'tcx
>
78 for Glb
<'combine
, 'infcx
, 'gcx
, 'tcx
>
80 fn infcx(&self) -> &'infcx InferCtxt
<'infcx
, 'gcx
, 'tcx
> {
84 fn cause(&self) -> &ObligationCause
<'tcx
> {
85 &self.fields
.trace
.cause
88 fn relate_bound(&mut self, v
: Ty
<'tcx
>, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, ()> {
89 let mut sub
= self.fields
.sub(self.a_is_expected
);