Skip to content

Commit ee227de

Browse files
committed
Remove LatticeDir trait.
It's no longer necessary now that the `glb` and `lub` modules have been merged.
1 parent 0aab101 commit ee227de

File tree

1 file changed

+69
-104
lines changed

1 file changed

+69
-104
lines changed

compiler/rustc_infer/src/infer/relate/lattice.rs

+69-104
Original file line numberDiff line numberDiff line change
@@ -26,96 +26,6 @@ use tracing::{debug, instrument};
2626
use super::StructurallyRelateAliases;
2727
use super::combine::{CombineFields, PredicateEmittingRelation};
2828
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
29-
use crate::traits::ObligationCause;
30-
31-
/// Trait for returning data about a lattice, and for abstracting
32-
/// over the "direction" of the lattice operation (LUB/GLB).
33-
///
34-
/// GLB moves "down" the lattice (to smaller values); LUB moves
35-
/// "up" the lattice (to bigger values).
36-
trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<InferCtxt<'tcx>> {
37-
fn infcx(&self) -> &'f InferCtxt<'tcx>;
38-
39-
fn cause(&self) -> &ObligationCause<'tcx>;
40-
41-
fn define_opaque_types(&self) -> DefineOpaqueTypes;
42-
43-
// Relates the type `v` to `a` and `b` such that `v` represents
44-
// the LUB/GLB of `a` and `b` as appropriate.
45-
//
46-
// Subtle hack: ordering *may* be significant here. This method
47-
// relates `v` to `a` first, which may help us to avoid unnecessary
48-
// type variable obligations. See caller for details.
49-
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>;
50-
}
51-
52-
/// Relates two types using a given lattice.
53-
#[instrument(skip(this), level = "debug")]
54-
fn super_lattice_tys<'a, 'tcx: 'a, L>(
55-
this: &mut L,
56-
a: Ty<'tcx>,
57-
b: Ty<'tcx>,
58-
) -> RelateResult<'tcx, Ty<'tcx>>
59-
where
60-
L: LatticeDir<'a, 'tcx>,
61-
{
62-
if a == b {
63-
return Ok(a);
64-
}
65-
66-
let infcx = this.infcx();
67-
68-
let a = infcx.shallow_resolve(a);
69-
let b = infcx.shallow_resolve(b);
70-
71-
match (a.kind(), b.kind()) {
72-
// If one side is known to be a variable and one is not,
73-
// create a variable (`v`) to represent the LUB. Make sure to
74-
// relate `v` to the non-type-variable first (by passing it
75-
// first to `relate_bound`). Otherwise, we would produce a
76-
// subtype obligation that must then be processed.
77-
//
78-
// Example: if the LHS is a type variable, and RHS is
79-
// `Box<i32>`, then we current compare `v` to the RHS first,
80-
// which will instantiate `v` with `Box<i32>`. Then when `v`
81-
// is compared to the LHS, we instantiate LHS with `Box<i32>`.
82-
// But if we did in reverse order, we would create a `v <:
83-
// LHS` (or vice versa) constraint and then instantiate
84-
// `v`. This would require further processing to achieve same
85-
// end-result; in particular, this screws up some of the logic
86-
// in coercion, which expects LUB to figure out that the LHS
87-
// is (e.g.) `Box<i32>`. A more obvious solution might be to
88-
// iterate on the subtype obligations that are returned, but I
89-
// think this suffices. -nmatsakis
90-
(&ty::Infer(TyVar(..)), _) => {
91-
let v = infcx.next_ty_var(this.cause().span);
92-
this.relate_bound(v, b, a)?;
93-
Ok(v)
94-
}
95-
(_, &ty::Infer(TyVar(..))) => {
96-
let v = infcx.next_ty_var(this.cause().span);
97-
this.relate_bound(v, a, b)?;
98-
Ok(v)
99-
}
100-
101-
(
102-
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
103-
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
104-
) if a_def_id == b_def_id => infcx.super_combine_tys(this, a, b),
105-
106-
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
107-
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
108-
if this.define_opaque_types() == DefineOpaqueTypes::Yes
109-
&& def_id.is_local()
110-
&& !this.infcx().next_trait_solver() =>
111-
{
112-
this.register_goals(infcx.handle_opaque_type(a, b, this.span(), this.param_env())?);
113-
Ok(a)
114-
}
115-
116-
_ => infcx.super_combine_tys(this, a, b),
117-
}
118-
}
11929

12030
#[derive(Clone, Copy)]
12131
pub(crate) enum LatticeOpKind {
@@ -173,9 +83,70 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
17383
}
17484
}
17585

86+
/// Relates two types using a given lattice.
17687
#[instrument(skip(self), level = "trace")]
17788
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
178-
super_lattice_tys(self, a, b)
89+
if a == b {
90+
return Ok(a);
91+
}
92+
93+
let infcx = self.fields.infcx;
94+
95+
let a = infcx.shallow_resolve(a);
96+
let b = infcx.shallow_resolve(b);
97+
98+
match (a.kind(), b.kind()) {
99+
// If one side is known to be a variable and one is not,
100+
// create a variable (`v`) to represent the LUB. Make sure to
101+
// relate `v` to the non-type-variable first (by passing it
102+
// first to `relate_bound`). Otherwise, we would produce a
103+
// subtype obligation that must then be processed.
104+
//
105+
// Example: if the LHS is a type variable, and RHS is
106+
// `Box<i32>`, then we current compare `v` to the RHS first,
107+
// which will instantiate `v` with `Box<i32>`. Then when `v`
108+
// is compared to the LHS, we instantiate LHS with `Box<i32>`.
109+
// But if we did in reverse order, we would create a `v <:
110+
// LHS` (or vice versa) constraint and then instantiate
111+
// `v`. This would require further processing to achieve same
112+
// end-result; in particular, this screws up some of the logic
113+
// in coercion, which expects LUB to figure out that the LHS
114+
// is (e.g.) `Box<i32>`. A more obvious solution might be to
115+
// iterate on the subtype obligations that are returned, but I
116+
// think this suffices. -nmatsakis
117+
(&ty::Infer(TyVar(..)), _) => {
118+
let v = infcx.next_ty_var(self.fields.trace.cause.span);
119+
self.relate_bound(v, b, a)?;
120+
Ok(v)
121+
}
122+
(_, &ty::Infer(TyVar(..))) => {
123+
let v = infcx.next_ty_var(self.fields.trace.cause.span);
124+
self.relate_bound(v, a, b)?;
125+
Ok(v)
126+
}
127+
128+
(
129+
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
130+
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
131+
) if a_def_id == b_def_id => infcx.super_combine_tys(self, a, b),
132+
133+
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
134+
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
135+
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
136+
&& def_id.is_local()
137+
&& !infcx.next_trait_solver() =>
138+
{
139+
self.register_goals(infcx.handle_opaque_type(
140+
a,
141+
b,
142+
self.span(),
143+
self.param_env(),
144+
)?);
145+
Ok(a)
146+
}
147+
148+
_ => infcx.super_combine_tys(self, a, b),
149+
}
179150
}
180151

181152
#[instrument(skip(self), level = "trace")]
@@ -231,15 +202,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
231202
}
232203
}
233204

234-
impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for LatticeOp<'combine, 'infcx, 'tcx> {
235-
fn infcx(&self) -> &'infcx InferCtxt<'tcx> {
236-
self.fields.infcx
237-
}
238-
239-
fn cause(&self) -> &ObligationCause<'tcx> {
240-
&self.fields.trace.cause
241-
}
242-
205+
impl<'combine, 'infcx, 'tcx> LatticeOp<'combine, 'infcx, 'tcx> {
206+
// Relates the type `v` to `a` and `b` such that `v` represents
207+
// the LUB/GLB of `a` and `b` as appropriate.
208+
//
209+
// Subtle hack: ordering *may* be significant here. This method
210+
// relates `v` to `a` first, which may help us to avoid unnecessary
211+
// type variable obligations. See caller for details.
243212
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
244213
let mut sub = self.fields.sub();
245214
match self.kind {
@@ -254,10 +223,6 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for LatticeOp<'combine, 'i
254223
}
255224
Ok(())
256225
}
257-
258-
fn define_opaque_types(&self) -> DefineOpaqueTypes {
259-
self.fields.define_opaque_types
260-
}
261226
}
262227

263228
impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {

0 commit comments

Comments
 (0)