Skip to content

Commit 5d28853

Browse files
authored
Rollup merge of #109462 - compiler-errors:alias-relate, r=BoxyUwU,lcnr
Make alias-eq have a relation direction (and rename it to alias-relate) Emitting an "alias-eq" is too strict in some situations, since we don't always want strict equality between a projection and rigid ty. Adds a relation direction. * I could probably just reuse this [`RelationDir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/combine/enum.RelationDir.html) -- happy to uplift that struct into middle and use that instead, but I didn't feel compelled to... 🤷 * Some of the matching in `compute_alias_relate_goal` is a bit verbose -- I guess I could simplify it by using [`At::relate`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/at/struct.At.html#method.relate) and mapping the relation-dir to a variance. * Alternatively, I coulld simplify things by making more helper functions on `EvalCtxt` (e.g. `EvalCtxt::relate_with_direction(T, T)` that also does the nested goal registration). No preference. r? ```@lcnr``` cc ```@BoxyUwU``` though boxy can claim it if she wants NOTE: first commit is all the changes, the second is just renaming stuff
2 parents a26ac4c + 244cdaa commit 5d28853

File tree

36 files changed

+260
-99
lines changed

36 files changed

+260
-99
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13351335
ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) => bug!(),
13361336
},
13371337
ty::PredicateKind::WellFormed(_)
1338-
| ty::PredicateKind::AliasEq(..)
1338+
| ty::PredicateKind::AliasRelate(..)
13391339
| ty::PredicateKind::ObjectSafe(_)
13401340
| ty::PredicateKind::ClosureKind(_, _, _)
13411341
| ty::PredicateKind::Subtype(_)

compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ fn trait_predicate_kind<'tcx>(
528528
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_))
529529
| ty::PredicateKind::Clause(ty::Clause::Projection(_))
530530
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
531-
| ty::PredicateKind::AliasEq(..)
531+
| ty::PredicateKind::AliasRelate(..)
532532
| ty::PredicateKind::WellFormed(_)
533533
| ty::PredicateKind::Subtype(_)
534534
| ty::PredicateKind::Coerce(_)

compiler/rustc_hir_analysis/src/outlives/explicit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
5656
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
5757
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
5858
| ty::PredicateKind::WellFormed(..)
59-
| ty::PredicateKind::AliasEq(..)
59+
| ty::PredicateKind::AliasRelate(..)
6060
| ty::PredicateKind::ObjectSafe(..)
6161
| ty::PredicateKind::ClosureKind(..)
6262
| ty::PredicateKind::Subtype(..)

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
666666
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
667667
| ty::PredicateKind::WellFormed(..)
668668
| ty::PredicateKind::ObjectSafe(..)
669-
| ty::PredicateKind::AliasEq(..)
669+
| ty::PredicateKind::AliasRelate(..)
670670
| ty::PredicateKind::ConstEvaluatable(..)
671671
| ty::PredicateKind::ConstEquate(..)
672672
// N.B., this predicate is created by breaking down a

compiler/rustc_hir_typeck/src/method/probe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
838838
| ty::PredicateKind::ConstEvaluatable(..)
839839
| ty::PredicateKind::ConstEquate(..)
840840
| ty::PredicateKind::Ambiguous
841-
| ty::PredicateKind::AliasEq(..)
841+
| ty::PredicateKind::AliasRelate(..)
842842
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
843843
}
844844
});

compiler/rustc_infer/src/infer/combine.rs

+11-9
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

@@ -842,23 +842,25 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
842842
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
843843

844844
self.register_predicates([ty::Binder::dummy(if self.tcx().trait_solver_next() {
845-
ty::PredicateKind::AliasEq(a.into(), b.into())
845+
ty::PredicateKind::AliasRelate(a.into(), b.into(), ty::AliasRelationDirection::Equate)
846846
} else {
847847
ty::PredicateKind::ConstEquate(a, b)
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>) {
855-
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
856-
857-
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasEq(
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>) {
854+
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
858855
a.into(),
859856
b.into(),
857+
self.alias_relate_direction(),
860858
))]);
861859
}
860+
861+
/// Relation direction emitted for `AliasRelate` predicates, corresponding to the direction
862+
/// of the relation.
863+
fn alias_relate_direction(&self) -> ty::AliasRelationDirection;
862864
}
863865

864866
fn int_unification_error<'tcx>(

compiler/rustc_infer/src/infer/equate.rs

+4
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,8 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> {
210210
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
211211
self.fields.register_obligations(obligations);
212212
}
213+
214+
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
215+
ty::AliasRelationDirection::Equate
216+
}
213217
}

compiler/rustc_infer/src/infer/glb.rs

+5
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,9 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
155155
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
156156
self.fields.register_obligations(obligations);
157157
}
158+
159+
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
160+
// FIXME(deferred_projection_equality): This isn't right, I think?
161+
ty::AliasRelationDirection::Equate
162+
}
158163
}

compiler/rustc_infer/src/infer/lub.rs

+5
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,9 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
155155
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
156156
self.fields.register_obligations(obligations)
157157
}
158+
159+
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
160+
// FIXME(deferred_projection_equality): This isn't right, I think?
161+
ty::AliasRelationDirection::Equate
162+
}
158163
}

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

+28
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,34 @@ where
711711
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
712712
self.delegate.register_obligations(obligations);
713713
}
714+
715+
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
716+
unreachable!("manually overridden to handle ty::Variance::Contravariant ambient variance")
717+
}
718+
719+
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
720+
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
721+
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
722+
a.into(),
723+
b.into(),
724+
ty::AliasRelationDirection::Subtype,
725+
),
726+
// a :> b is b <: a
727+
ty::Variance::Contravariant => ty::PredicateKind::AliasRelate(
728+
b.into(),
729+
a.into(),
730+
ty::AliasRelationDirection::Subtype,
731+
),
732+
ty::Variance::Invariant => ty::PredicateKind::AliasRelate(
733+
a.into(),
734+
b.into(),
735+
ty::AliasRelationDirection::Equate,
736+
),
737+
// FIXME(deferred_projection_equality): Implement this when we trigger it.
738+
// Probably just need to do nothing here.
739+
ty::Variance::Bivariant => unreachable!(),
740+
})]);
741+
}
714742
}
715743

716744
/// When we encounter a binder like `for<..> fn(..)`, we actually have

compiler/rustc_infer/src/infer/outlives/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn explicit_outlives_bounds<'tcx>(
2222
ty::PredicateKind::Clause(ty::Clause::Projection(..))
2323
| ty::PredicateKind::Clause(ty::Clause::Trait(..))
2424
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
25-
| ty::PredicateKind::AliasEq(..)
25+
| ty::PredicateKind::AliasRelate(..)
2626
| ty::PredicateKind::Coerce(..)
2727
| ty::PredicateKind::Subtype(..)
2828
| ty::PredicateKind::WellFormed(..)

compiler/rustc_infer/src/infer/projection.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl<'tcx> InferCtxt<'tcx> {
2626
// completely change the normalization routine with the new solver.
2727
//
2828
// The new solver correctly handles projection equality so this hack
29-
// is not necessary. if re-enabled it should emit `PredicateKind::AliasEq`
29+
// is not necessary. if re-enabled it should emit `PredicateKind::AliasRelate`
3030
// not `PredicateKind::Clause(Clause::Projection(..))` as in the new solver
3131
// `Projection` is used as `normalizes-to` which will fail for `<T as Trait>::Assoc eq ?0`.
3232
return projection_ty.to_ty(self.tcx);

compiler/rustc_infer/src/infer/sub.rs

+4
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,8 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> {
236236
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
237237
self.fields.register_obligations(obligations);
238238
}
239+
240+
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
241+
ty::AliasRelationDirection::Subtype
242+
}
239243
}

compiler/rustc_infer/src/traits/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ impl<'tcx> Elaborator<'tcx> {
293293
// Nothing to elaborate
294294
}
295295
ty::PredicateKind::Ambiguous => {}
296-
ty::PredicateKind::AliasEq(..) => {
296+
ty::PredicateKind::AliasRelate(..) => {
297297
// No
298298
}
299299
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => {

compiler/rustc_lint/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
16011601
// Ignore projections, as they can only be global
16021602
// if the trait bound is global
16031603
Clause(Clause::Projection(..)) |
1604-
AliasEq(..) |
1604+
AliasRelate(..) |
16051605
// Ignore bounds that a user can't type
16061606
WellFormed(..) |
16071607
ObjectSafe(..) |

compiler/rustc_middle/src/ty/flags.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ impl FlagComputation {
288288
self.add_ty(ty);
289289
}
290290
ty::PredicateKind::Ambiguous => {}
291-
ty::PredicateKind::AliasEq(t1, t2) => {
291+
ty::PredicateKind::AliasRelate(t1, t2, _) => {
292292
self.add_term(t1);
293293
self.add_term(t2);
294294
}

compiler/rustc_middle/src/ty/mod.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ impl<'tcx> Predicate<'tcx> {
543543
| PredicateKind::Clause(Clause::TypeOutlives(_))
544544
| PredicateKind::Clause(Clause::Projection(_))
545545
| PredicateKind::Clause(Clause::ConstArgHasType(..))
546-
| PredicateKind::AliasEq(..)
546+
| PredicateKind::AliasRelate(..)
547547
| PredicateKind::ObjectSafe(_)
548548
| PredicateKind::ClosureKind(_, _, _)
549549
| PredicateKind::Subtype(_)
@@ -640,7 +640,23 @@ pub enum PredicateKind<'tcx> {
640640
/// This predicate requires two terms to be equal to eachother.
641641
///
642642
/// Only used for new solver
643-
AliasEq(Term<'tcx>, Term<'tcx>),
643+
AliasRelate(Term<'tcx>, Term<'tcx>, AliasRelationDirection),
644+
}
645+
646+
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
647+
#[derive(HashStable, Debug)]
648+
pub enum AliasRelationDirection {
649+
Equate,
650+
Subtype,
651+
}
652+
653+
impl std::fmt::Display for AliasRelationDirection {
654+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
655+
match self {
656+
AliasRelationDirection::Equate => write!(f, " == "),
657+
AliasRelationDirection::Subtype => write!(f, " <: "),
658+
}
659+
}
644660
}
645661

646662
/// The crate outlives map is computed during typeck and contains the
@@ -976,11 +992,11 @@ impl<'tcx> Term<'tcx> {
976992
}
977993
}
978994

979-
/// This function returns `None` for `AliasKind::Opaque`.
995+
/// This function returns the inner `AliasTy` if this term is a projection.
980996
///
981997
/// FIXME: rename `AliasTy` to `AliasTerm` and make sure we correctly
982998
/// deal with constants.
983-
pub fn to_alias_term_no_opaque(&self, tcx: TyCtxt<'tcx>) -> Option<AliasTy<'tcx>> {
999+
pub fn to_projection_term(&self, tcx: TyCtxt<'tcx>) -> Option<AliasTy<'tcx>> {
9841000
match self.unpack() {
9851001
TermKind::Ty(ty) => match ty.kind() {
9861002
ty::Alias(kind, alias_ty) => match kind {
@@ -1206,7 +1222,7 @@ impl<'tcx> Predicate<'tcx> {
12061222
PredicateKind::Clause(Clause::Trait(t)) => Some(predicate.rebind(t)),
12071223
PredicateKind::Clause(Clause::Projection(..))
12081224
| PredicateKind::Clause(Clause::ConstArgHasType(..))
1209-
| PredicateKind::AliasEq(..)
1225+
| PredicateKind::AliasRelate(..)
12101226
| PredicateKind::Subtype(..)
12111227
| PredicateKind::Coerce(..)
12121228
| PredicateKind::Clause(Clause::RegionOutlives(..))
@@ -1227,7 +1243,7 @@ impl<'tcx> Predicate<'tcx> {
12271243
PredicateKind::Clause(Clause::Projection(t)) => Some(predicate.rebind(t)),
12281244
PredicateKind::Clause(Clause::Trait(..))
12291245
| PredicateKind::Clause(Clause::ConstArgHasType(..))
1230-
| PredicateKind::AliasEq(..)
1246+
| PredicateKind::AliasRelate(..)
12311247
| PredicateKind::Subtype(..)
12321248
| PredicateKind::Coerce(..)
12331249
| PredicateKind::Clause(Clause::RegionOutlives(..))
@@ -1249,7 +1265,7 @@ impl<'tcx> Predicate<'tcx> {
12491265
PredicateKind::Clause(Clause::Trait(..))
12501266
| PredicateKind::Clause(Clause::ConstArgHasType(..))
12511267
| PredicateKind::Clause(Clause::Projection(..))
1252-
| PredicateKind::AliasEq(..)
1268+
| PredicateKind::AliasRelate(..)
12531269
| PredicateKind::Subtype(..)
12541270
| PredicateKind::Coerce(..)
12551271
| PredicateKind::Clause(Clause::RegionOutlives(..))

compiler/rustc_middle/src/ty/print/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2847,7 +2847,7 @@ define_print_and_forward_display! {
28472847
p!("the type `", print(ty), "` is found in the environment")
28482848
}
28492849
ty::PredicateKind::Ambiguous => p!("ambiguous"),
2850-
ty::PredicateKind::AliasEq(t1, t2) => p!(print(t1), " == ", print(t2)),
2850+
ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)),
28512851
}
28522852
}
28532853

compiler/rustc_middle/src/ty/structural_impls.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
177177
write!(f, "TypeWellFormedFromEnv({:?})", ty)
178178
}
179179
ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
180-
ty::PredicateKind::AliasEq(t1, t2) => write!(f, "AliasEq({t1:?}, {t2:?})"),
180+
ty::PredicateKind::AliasRelate(t1, t2, dir) => {
181+
write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})")
182+
}
181183
}
182184
}
183185
}
@@ -250,6 +252,7 @@ TrivialTypeTraversalAndLiftImpls! {
250252
crate::ty::AssocItem,
251253
crate::ty::AssocKind,
252254
crate::ty::AliasKind,
255+
crate::ty::AliasRelationDirection,
253256
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
254257
crate::ty::Placeholder<crate::ty::BoundTyKind>,
255258
crate::ty::ClosureKind,

compiler/rustc_privacy/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ where
180180
| ty::PredicateKind::ConstEquate(_, _)
181181
| ty::PredicateKind::TypeWellFormedFromEnv(_)
182182
| ty::PredicateKind::Ambiguous
183-
| ty::PredicateKind::AliasEq(_, _) => bug!("unexpected predicate: {:?}", predicate),
183+
| ty::PredicateKind::AliasRelate(..) => bug!("unexpected predicate: {:?}", predicate),
184184
}
185185
}
186186

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
223223
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
224224
bug!("TypeWellFormedFromEnv is only used for Chalk")
225225
}
226-
ty::PredicateKind::AliasEq(lhs, rhs) => {
227-
self.compute_alias_eq_goal(Goal { param_env, predicate: (lhs, rhs) })
228-
}
226+
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => self
227+
.compute_alias_relate_goal(Goal {
228+
param_env,
229+
predicate: (lhs, rhs, direction),
230+
}),
229231
}
230232
} else {
231233
let kind = self.infcx.instantiate_binder_with_placeholders(kind);
@@ -457,6 +459,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
457459
})
458460
}
459461

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+
460481
/// Equates two values returning the nested goals without adding them
461482
/// to the nested goals of the `EvalCtxt`.
462483
///

compiler/rustc_trait_selection/src/solve/fulfill.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
7373
MismatchedProjectionTypes { err: TypeError::Mismatch },
7474
)
7575
}
76-
ty::PredicateKind::AliasEq(_, _) => {
76+
ty::PredicateKind::AliasRelate(_, _, _) => {
7777
FulfillmentErrorCode::CodeProjectionError(
7878
MismatchedProjectionTypes { err: TypeError::Mismatch },
7979
)

0 commit comments

Comments
 (0)