Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 244cdaa

Browse files
committedMar 23, 2023
Remove AliasRelationDirection::Supertype
1 parent f6fd754 commit 244cdaa

File tree

5 files changed

+99
-91
lines changed

5 files changed

+99
-91
lines changed
 

‎compiler/rustc_infer/src/infer/combine.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> {
128128
(_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _)
129129
if self.tcx.trait_solver_next() =>
130130
{
131-
relation.register_type_equate_obligation(a, b);
131+
relation.register_type_relate_obligation(a, b);
132132
Ok(a)
133133
}
134134

@@ -848,18 +848,18 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
848848
})]);
849849
}
850850

851-
/// Register an obligation that both types must be equal to each other.
852-
///
853-
/// If they aren't equal then the relation doesn't hold.
854-
fn register_type_equate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
851+
/// Register an obligation that both types must be related to each other according to
852+
/// the [`ty::AliasRelationDirection`] given by [`ObligationEmittingRelation::alias_relate_direction`]
853+
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
855854
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
856855
a.into(),
857856
b.into(),
858857
self.alias_relate_direction(),
859858
))]);
860859
}
861860

862-
/// Relation direction emitted for `AliasRelate` predicates
861+
/// Relation direction emitted for `AliasRelate` predicates, corresponding to the direction
862+
/// of the relation.
863863
fn alias_relate_direction(&self) -> ty::AliasRelationDirection;
864864
}
865865

‎compiler/rustc_infer/src/infer/nll_relate/mod.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -779,13 +779,31 @@ where
779779
}
780780

781781
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
782-
match self.ambient_variance {
783-
ty::Variance::Covariant => ty::AliasRelationDirection::Subtype,
784-
ty::Variance::Contravariant => ty::AliasRelationDirection::Supertype,
785-
ty::Variance::Invariant => ty::AliasRelationDirection::Equate,
786-
// FIXME(deferred_projection_equality): Implement this when we trigger it
782+
unreachable!("manually overridden to handle ty::Variance::Contravariant ambient variance")
783+
}
784+
785+
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
786+
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
787+
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
788+
a.into(),
789+
b.into(),
790+
ty::AliasRelationDirection::Subtype,
791+
),
792+
// a :> b is b <: a
793+
ty::Variance::Contravariant => ty::PredicateKind::AliasRelate(
794+
b.into(),
795+
a.into(),
796+
ty::AliasRelationDirection::Subtype,
797+
),
798+
ty::Variance::Invariant => ty::PredicateKind::AliasRelate(
799+
a.into(),
800+
b.into(),
801+
ty::AliasRelationDirection::Equate,
802+
),
803+
// FIXME(deferred_projection_equality): Implement this when we trigger it.
804+
// Probably just need to do nothing here.
787805
ty::Variance::Bivariant => unreachable!(),
788-
}
806+
})]);
789807
}
790808
}
791809

‎compiler/rustc_middle/src/ty/mod.rs

-12
Original file line numberDiff line numberDiff line change
@@ -648,25 +648,13 @@ pub enum PredicateKind<'tcx> {
648648
pub enum AliasRelationDirection {
649649
Equate,
650650
Subtype,
651-
Supertype,
652-
}
653-
654-
impl AliasRelationDirection {
655-
pub fn invert(self) -> Self {
656-
match self {
657-
AliasRelationDirection::Equate => AliasRelationDirection::Equate,
658-
AliasRelationDirection::Subtype => AliasRelationDirection::Supertype,
659-
AliasRelationDirection::Supertype => AliasRelationDirection::Subtype,
660-
}
661-
}
662651
}
663652

664653
impl std::fmt::Display for AliasRelationDirection {
665654
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
666655
match self {
667656
AliasRelationDirection::Equate => write!(f, " == "),
668657
AliasRelationDirection::Subtype => write!(f, " <: "),
669-
AliasRelationDirection::Supertype => write!(f, " :> "),
670658
}
671659
}
672660
}

‎compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+19
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
459459
})
460460
}
461461

462+
#[instrument(level = "debug", skip(self, param_env), ret)]
463+
pub(super) fn sub<T: ToTrace<'tcx>>(
464+
&mut self,
465+
param_env: ty::ParamEnv<'tcx>,
466+
sub: T,
467+
sup: T,
468+
) -> Result<(), NoSolution> {
469+
self.infcx
470+
.at(&ObligationCause::dummy(), param_env)
471+
.sub(DefineOpaqueTypes::No, sub, sup)
472+
.map(|InferOk { value: (), obligations }| {
473+
self.add_goals(obligations.into_iter().map(|o| o.into()));
474+
})
475+
.map_err(|e| {
476+
debug!(?e, "failed to subtype");
477+
NoSolution
478+
})
479+
}
480+
462481
/// Equates two values returning the nested goals without adding them
463482
/// to the nested goals of the `EvalCtxt`.
464483
///

‎compiler/rustc_trait_selection/src/solve/mod.rs

+50-67
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
use rustc_hir::def_id::DefId;
1919
use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
20-
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
2120
use rustc_infer::traits::query::NoSolution;
2221
use rustc_middle::traits::solve::{
2322
CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraints, ExternalConstraintsData,
@@ -101,11 +100,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
101100
// That won't actually reflect in the query response, so it seems moot.
102101
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
103102
} else {
104-
let InferOk { value: (), obligations } = self
105-
.infcx
106-
.at(&ObligationCause::dummy(), goal.param_env)
107-
.sub(DefineOpaqueTypes::No, goal.predicate.a, goal.predicate.b)?;
108-
self.add_goals(obligations.into_iter().map(|pred| pred.into()));
103+
self.sub(goal.param_env, goal.predicate.a, goal.predicate.b)?;
109104
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
110105
}
111106
}
@@ -161,44 +156,41 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
161156
goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>,
162157
) -> QueryResult<'tcx> {
163158
let tcx = self.tcx();
164-
165-
let evaluate_normalizes_to = |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other, direction| {
166-
debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other);
167-
let result = ecx.probe(|ecx| {
168-
let other = match direction {
169-
// This is purely an optimization.
170-
ty::AliasRelationDirection::Equate => other,
171-
172-
ty::AliasRelationDirection::Subtype | ty::AliasRelationDirection::Supertype => {
173-
let fresh = ecx.next_term_infer_of_kind(other);
174-
let (sub, sup) = if direction == ty::AliasRelationDirection::Subtype {
175-
(fresh, other)
176-
} else {
177-
(other, fresh)
178-
};
179-
ecx.add_goals(
180-
ecx.infcx
181-
.at(&ObligationCause::dummy(), goal.param_env)
182-
.sub(DefineOpaqueTypes::No, sub, sup)?
183-
.into_obligations()
184-
.into_iter()
185-
.map(|o| o.into()),
186-
);
187-
fresh
188-
}
189-
};
190-
ecx.add_goal(goal.with(
191-
tcx,
192-
ty::Binder::dummy(ty::ProjectionPredicate {
193-
projection_ty: alias,
194-
term: other,
195-
}),
196-
));
197-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
198-
});
199-
debug!("evaluate_normalizes_to({alias}, {other}, {direction:?}) -> {result:?}");
200-
result
201-
};
159+
// We may need to invert the alias relation direction if dealing an alias on the RHS.
160+
enum Invert {
161+
No,
162+
Yes,
163+
}
164+
let evaluate_normalizes_to =
165+
|ecx: &mut EvalCtxt<'_, 'tcx>, alias, other, direction, invert| {
166+
debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other);
167+
let result = ecx.probe(|ecx| {
168+
let other = match direction {
169+
// This is purely an optimization.
170+
ty::AliasRelationDirection::Equate => other,
171+
172+
ty::AliasRelationDirection::Subtype => {
173+
let fresh = ecx.next_term_infer_of_kind(other);
174+
let (sub, sup) = match invert {
175+
Invert::No => (fresh, other),
176+
Invert::Yes => (other, fresh),
177+
};
178+
ecx.sub(goal.param_env, sub, sup)?;
179+
fresh
180+
}
181+
};
182+
ecx.add_goal(goal.with(
183+
tcx,
184+
ty::Binder::dummy(ty::ProjectionPredicate {
185+
projection_ty: alias,
186+
term: other,
187+
}),
188+
));
189+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
190+
});
191+
debug!("evaluate_normalizes_to({alias}, {other}, {direction:?}) -> {result:?}");
192+
result
193+
};
202194

203195
let (lhs, rhs, direction) = goal.predicate;
204196

@@ -212,46 +204,37 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
212204
(None, None) => bug!("`AliasRelate` goal without an alias on either lhs or rhs"),
213205

214206
// RHS is not a projection, only way this is true is if LHS normalizes-to RHS
215-
(Some(alias_lhs), None) => evaluate_normalizes_to(self, alias_lhs, rhs, direction),
207+
(Some(alias_lhs), None) => {
208+
evaluate_normalizes_to(self, alias_lhs, rhs, direction, Invert::No)
209+
}
216210

217211
// LHS is not a projection, only way this is true is if RHS normalizes-to LHS
218212
(None, Some(alias_rhs)) => {
219-
evaluate_normalizes_to(self, alias_rhs, lhs, direction.invert())
213+
evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes)
220214
}
221215

222216
(Some(alias_lhs), Some(alias_rhs)) => {
223217
debug!("compute_alias_relate_goal: both sides are aliases");
224218

225219
let candidates = vec![
226220
// LHS normalizes-to RHS
227-
evaluate_normalizes_to(self, alias_lhs, rhs, direction),
221+
evaluate_normalizes_to(self, alias_lhs, rhs, direction, Invert::No),
228222
// RHS normalizes-to RHS
229-
evaluate_normalizes_to(self, alias_rhs, lhs, direction.invert()),
223+
evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes),
230224
// Relate via substs
231225
self.probe(|ecx| {
232226
debug!(
233227
"compute_alias_relate_goal: alias defids are equal, equating substs"
234228
);
235229

236-
ecx.add_goals(
237-
match direction {
238-
ty::AliasRelationDirection::Equate => ecx
239-
.infcx
240-
.at(&ObligationCause::dummy(), goal.param_env)
241-
.eq(DefineOpaqueTypes::No, alias_lhs, alias_rhs),
242-
ty::AliasRelationDirection::Subtype => ecx
243-
.infcx
244-
.at(&ObligationCause::dummy(), goal.param_env)
245-
.sub(DefineOpaqueTypes::No, alias_lhs, alias_rhs),
246-
ty::AliasRelationDirection::Supertype => ecx
247-
.infcx
248-
.at(&ObligationCause::dummy(), goal.param_env)
249-
.sup(DefineOpaqueTypes::No, alias_lhs, alias_rhs),
250-
}?
251-
.into_obligations()
252-
.into_iter()
253-
.map(|o| o.into()),
254-
);
230+
match direction {
231+
ty::AliasRelationDirection::Equate => {
232+
ecx.eq(goal.param_env, alias_lhs, alias_rhs)?;
233+
}
234+
ty::AliasRelationDirection::Subtype => {
235+
ecx.sub(goal.param_env, alias_lhs, alias_rhs)?;
236+
}
237+
}
255238

256239
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
257240
}),

0 commit comments

Comments
 (0)