1 use super::combine
::CombineFields
;
2 use super::lattice
::{self, LatticeDir}
;
6 use crate::traits
::ObligationCause
;
7 use rustc_middle
::ty
::relate
::{Relate, RelateResult, TypeRelation}
;
8 use rustc_middle
::ty
::{self, Ty, TyCtxt}
;
10 /// "Least upper bound" (common supertype)
11 pub struct Lub
<'combine
, 'infcx
, 'tcx
> {
12 fields
: &'combine
mut CombineFields
<'infcx
, 'tcx
>,
16 impl<'combine
, 'infcx
, 'tcx
> Lub
<'combine
, 'infcx
, 'tcx
> {
18 fields
: &'combine
mut CombineFields
<'infcx
, 'tcx
>,
20 ) -> Lub
<'combine
, 'infcx
, 'tcx
> {
21 Lub { fields, a_is_expected }
25 impl TypeRelation
<'tcx
> for Lub
<'combine
, 'infcx
, 'tcx
> {
26 fn tag(&self) -> &'
static str {
30 fn tcx(&self) -> TyCtxt
<'tcx
> {
34 fn param_env(&self) -> ty
::ParamEnv
<'tcx
> {
38 fn a_is_expected(&self) -> bool
{
42 fn relate_with_variance
<T
: Relate
<'tcx
>>(
44 variance
: ty
::Variance
,
47 ) -> RelateResult
<'tcx
, T
> {
49 ty
::Invariant
=> self.fields
.equate(self.a_is_expected
).relate(a
, b
),
50 ty
::Covariant
=> self.relate(a
, b
),
51 // FIXME(#41044) -- not correct, need test
52 ty
::Bivariant
=> Ok(a
.clone()),
53 ty
::Contravariant
=> self.fields
.glb(self.a_is_expected
).relate(a
, b
),
57 fn tys(&mut self, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, Ty
<'tcx
>> {
58 lattice
::super_lattice_tys(self, a
, b
)
65 ) -> RelateResult
<'tcx
, ty
::Region
<'tcx
>> {
66 debug
!("{}.regions({:?}, {:?})", self.tag(), a
, b
);
68 let origin
= Subtype(box self.fields
.trace
.clone());
69 Ok(self.fields
.infcx
.inner
.borrow_mut().unwrap_region_constraints().lub_regions(
79 a
: &'tcx ty
::Const
<'tcx
>,
80 b
: &'tcx ty
::Const
<'tcx
>,
81 ) -> RelateResult
<'tcx
, &'tcx ty
::Const
<'tcx
>> {
82 self.fields
.infcx
.super_combine_consts(self, a
, b
)
89 ) -> RelateResult
<'tcx
, ty
::Binder
<T
>>
93 debug
!("binders(a={:?}, b={:?})", a
, b
);
95 // When higher-ranked types are involved, computing the LUB is
96 // very challenging, switch to invariance. This is obviously
97 // overly conservative but works ok in practice.
98 self.relate_with_variance(ty
::Variance
::Invariant
, a
, b
)?
;
103 impl<'combine
, 'infcx
, 'tcx
> LatticeDir
<'infcx
, 'tcx
> for Lub
<'combine
, 'infcx
, 'tcx
> {
104 fn infcx(&self) -> &'infcx InferCtxt
<'infcx
, 'tcx
> {
108 fn cause(&self) -> &ObligationCause
<'tcx
> {
109 &self.fields
.trace
.cause
112 fn relate_bound(&mut self, v
: Ty
<'tcx
>, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, ()> {
113 let mut sub
= self.fields
.sub(self.a_is_expected
);