Skip to content

Commit

Permalink
Remove a_is_expected from combine relations
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Feb 26, 2024
1 parent 46a7e24 commit 968abf3
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 134 deletions.
1 change: 0 additions & 1 deletion compiler/rustc_borrowck/src/type_check/relate_tys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let infcx = self.type_checker.infcx;
debug_assert!(!infcx.next_trait_solver());
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
// `handle_opaque_type` cannot handle subtyping, so to support subtyping
// we instead eagerly generalize here. This is a bit of a mess but will go
// away once we're using the new solver.
Expand Down
91 changes: 29 additions & 62 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ pub struct At<'a, 'tcx> {

pub struct Trace<'a, 'tcx> {
at: At<'a, 'tcx>,
a_is_expected: bool,
trace: TypeTrace<'tcx>,
}

Expand Down Expand Up @@ -106,23 +105,6 @@ pub trait ToTrace<'tcx>: Relate<'tcx> + Copy {
}

impl<'a, 'tcx> At<'a, 'tcx> {
/// Makes `a <: b`, where `a` may or may not be expected.
///
/// See [`At::trace_exp`] and [`Trace::sub`] for a version of
/// this method that only requires `T: Relate<'tcx>`
pub fn sub_exp<T>(
self,
define_opaque_types: DefineOpaqueTypes,
a_is_expected: bool,
a: T,
b: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
self.trace_exp(a_is_expected, a, b).sub(define_opaque_types, a, b)
}

/// Makes `actual <: expected`. For example, if type-checking a
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
/// `sup(i32, x)`, since the "expected" type is the type that
Expand All @@ -139,7 +121,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
self.sub_exp(define_opaque_types, false, actual, expected)
self.trace(expected, actual).sup(define_opaque_types, expected, actual)
}

/// Makes `expected <: actual`.
Expand All @@ -155,24 +137,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
self.sub_exp(define_opaque_types, true, expected, actual)
}

/// Makes `expected <: actual`.
///
/// See [`At::trace_exp`] and [`Trace::eq`] for a version of
/// this method that only requires `T: Relate<'tcx>`
pub fn eq_exp<T>(
self,
define_opaque_types: DefineOpaqueTypes,
a_is_expected: bool,
a: T,
b: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
self.trace_exp(a_is_expected, a, b).eq(define_opaque_types, a, b)
self.trace(expected, actual).sub(define_opaque_types, expected, actual)
}

/// Makes `expected <: actual`.
Expand Down Expand Up @@ -261,48 +226,50 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
self.trace_exp(true, expected, actual)
let trace = ToTrace::to_trace(self.cause, true, expected, actual);
Trace { at: self, trace }
}
}

/// Like `trace`, but the expected value is determined by the
/// boolean argument (if true, then the first argument `a` is the
/// "expected" value).
pub fn trace_exp<T>(self, a_is_expected: bool, a: T, b: T) -> Trace<'a, 'tcx>
impl<'a, 'tcx> Trace<'a, 'tcx> {
/// Makes `a <: b`.
#[instrument(skip(self), level = "debug")]
pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
T: Relate<'tcx>,
{
let trace = ToTrace::to_trace(self.cause, a_is_expected, a, b);
Trace { at: self, trace, a_is_expected }
let Trace { at, trace } = self;
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.sub()
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
}
}

impl<'a, 'tcx> Trace<'a, 'tcx> {
/// Makes `a <: b` where `a` may or may not be expected (if
/// `a_is_expected` is true, then `a` is expected).
/// Makes `a :> b`.
#[instrument(skip(self), level = "debug")]
pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
pub fn sup<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
where
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
let Trace { at, trace } = self;
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.sub(a_is_expected)
.sup()
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
}

/// Makes `a == b`; the expectation is set by the call to
/// `trace()`.
/// Makes `a == b`.
#[instrument(skip(self), level = "debug")]
pub fn eq<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
where
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
let Trace { at, trace } = self;
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.equate(StructurallyRelateAliases::No, a_is_expected)
.equate(StructurallyRelateAliases::No)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
}
Expand All @@ -314,11 +281,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
where
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
let Trace { at, trace } = self;
debug_assert!(at.infcx.next_trait_solver());
let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::No);
fields
.equate(StructurallyRelateAliases::Yes, a_is_expected)
.equate(StructurallyRelateAliases::Yes)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
}
Expand All @@ -328,10 +295,10 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
where
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
let Trace { at, trace } = self;
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.lub(a_is_expected)
.lub()
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
}
Expand All @@ -341,10 +308,10 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
where
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
let Trace { at, trace } = self;
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.glb(a_is_expected)
.glb()
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
}
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,13 +522,7 @@ impl<'tcx> InferCtxt<'tcx> {
) -> InferResult<'tcx, ()> {
let mut obligations = Vec::new();

self.insert_hidden_type(
opaque_type_key,
&cause,
param_env,
hidden_ty,
&mut obligations,
)?;
self.insert_hidden_type(opaque_type_key, &cause, param_env, hidden_ty, &mut obligations)?;

self.add_item_bounds_for_hidden_type(
opaque_type_key.def_id.to_def_id(),
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_infer/src/infer/relate/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,21 +321,24 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
pub fn equate<'a>(
&'a mut self,
structurally_relate_aliases: StructurallyRelateAliases,
a_is_expected: bool,
) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, a_is_expected, structurally_relate_aliases, ty::Invariant)
TypeRelating::new(self, structurally_relate_aliases, ty::Invariant)
}

pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, a_is_expected, StructurallyRelateAliases::No, ty::Covariant)
pub fn sub<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Covariant)
}

pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'tcx> {
Lub::new(self, a_is_expected)
pub fn sup<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Contravariant)
}

pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'tcx> {
Glb::new(self, a_is_expected)
pub fn lub<'a>(&'a mut self) -> Lub<'a, 'infcx, 'tcx> {
Lub::new(self)
}

pub fn glb<'a>(&'a mut self) -> Glb<'a, 'infcx, 'tcx> {
Glb::new(self)
}

pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
Expand Down
18 changes: 6 additions & 12 deletions compiler/rustc_infer/src/infer/relate/glb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ use crate::traits::{ObligationCause, PredicateObligations};
/// "Greatest lower bound" (common subtype)
pub struct Glb<'combine, 'infcx, 'tcx> {
fields: &'combine mut CombineFields<'infcx, 'tcx>,
a_is_expected: bool,
}

impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
pub fn new(
fields: &'combine mut CombineFields<'infcx, 'tcx>,
a_is_expected: bool,
) -> Glb<'combine, 'infcx, 'tcx> {
Glb { fields, a_is_expected }
pub fn new(fields: &'combine mut CombineFields<'infcx, 'tcx>) -> Glb<'combine, 'infcx, 'tcx> {
Glb { fields }
}
}

Expand All @@ -35,7 +31,7 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
}

fn a_is_expected(&self) -> bool {
self.a_is_expected
true
}

fn relate_with_variance<T: Relate<'tcx>>(
Expand All @@ -46,13 +42,11 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
b: T,
) -> RelateResult<'tcx, T> {
match variance {
ty::Invariant => {
self.fields.equate(StructurallyRelateAliases::No, self.a_is_expected).relate(a, b)
}
ty::Invariant => self.fields.equate(StructurallyRelateAliases::No).relate(a, b),
ty::Covariant => self.relate(a, b),
// FIXME(#41044) -- not correct, need test
ty::Bivariant => Ok(a),
ty::Contravariant => self.fields.lub(self.a_is_expected).relate(a, b),
ty::Contravariant => self.fields.lub().relate(a, b),
}
}

Expand Down Expand Up @@ -126,7 +120,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
}

fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub(self.a_is_expected);
let mut sub = self.fields.sub();
sub.relate(v, a)?;
sub.relate(v, b)?;
Ok(())
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_infer/src/infer/relate/higher_ranked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
debug!("b_prime={:?}", sup_prime);

// Compare types now that bound regions have been replaced.
let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime);
// Reorder the inputs so that the expected is passed first.
let result = if sub_is_expected {
self.sub().relate(sub_prime, sup_prime)
} else {
self.sup().relate(sup_prime, sub_prime)
};

if result.is_ok() {
debug!("OK result={result:?}");
}
Expand Down
18 changes: 6 additions & 12 deletions compiler/rustc_infer/src/infer/relate/lub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ use rustc_span::Span;
/// "Least upper bound" (common supertype)
pub struct Lub<'combine, 'infcx, 'tcx> {
fields: &'combine mut CombineFields<'infcx, 'tcx>,
a_is_expected: bool,
}

impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
pub fn new(
fields: &'combine mut CombineFields<'infcx, 'tcx>,
a_is_expected: bool,
) -> Lub<'combine, 'infcx, 'tcx> {
Lub { fields, a_is_expected }
pub fn new(fields: &'combine mut CombineFields<'infcx, 'tcx>) -> Lub<'combine, 'infcx, 'tcx> {
Lub { fields }
}
}

Expand All @@ -35,7 +31,7 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
}

fn a_is_expected(&self) -> bool {
self.a_is_expected
true
}

fn relate_with_variance<T: Relate<'tcx>>(
Expand All @@ -46,13 +42,11 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
b: T,
) -> RelateResult<'tcx, T> {
match variance {
ty::Invariant => {
self.fields.equate(StructurallyRelateAliases::No, self.a_is_expected).relate(a, b)
}
ty::Invariant => self.fields.equate(StructurallyRelateAliases::No).relate(a, b),
ty::Covariant => self.relate(a, b),
// FIXME(#41044) -- not correct, need test
ty::Bivariant => Ok(a),
ty::Contravariant => self.fields.glb(self.a_is_expected).relate(a, b),
ty::Contravariant => self.fields.glb().relate(a, b),
}
}

Expand Down Expand Up @@ -126,7 +120,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
}

fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub(self.a_is_expected);
let mut sub = self.fields.sub();
sub.relate(a, v)?;
sub.relate(b, v)?;
Ok(())
Expand Down
Loading

0 comments on commit 968abf3

Please sign in to comment.