From 5dc3fd7c05010654b4d80b87eac8c937e4808607 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Mar 2023 21:50:16 +0000 Subject: [PATCH 1/4] Include relation direction in AliasEq predicate --- compiler/rustc_infer/src/infer/combine.rs | 8 +- compiler/rustc_infer/src/infer/equate.rs | 4 + compiler/rustc_infer/src/infer/glb.rs | 5 + compiler/rustc_infer/src/infer/lub.rs | 5 + .../rustc_infer/src/infer/nll_relate/mod.rs | 10 ++ compiler/rustc_infer/src/infer/sub.rs | 4 + compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 24 ++++- compiler/rustc_middle/src/ty/print/pretty.rs | 3 +- .../rustc_middle/src/ty/structural_impls.rs | 4 +- compiler/rustc_privacy/src/lib.rs | 2 +- .../src/solve/eval_ctxt.rs | 4 +- .../src/solve/fulfill.rs | 2 +- .../rustc_trait_selection/src/solve/mod.rs | 95 ++++++++++++++----- .../traits/error_reporting/method_chain.rs | 5 + tests/ui/traits/new-solver/alias-sub.rs | 34 +++++++ 16 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 tests/ui/traits/new-solver/alias-sub.rs diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 4503af03ca341..c82438f05e140 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -842,7 +842,7 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) }; self.register_predicates([ty::Binder::dummy(if self.tcx().trait_solver_next() { - ty::PredicateKind::AliasEq(a.into(), b.into()) + ty::PredicateKind::AliasEq(a.into(), b.into(), ty::AliasRelationDirection::Equate) } else { ty::PredicateKind::ConstEquate(a, b) })]); @@ -852,13 +852,15 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { /// /// If they aren't equal then the relation doesn't hold. fn register_type_equate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { - let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) }; - self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasEq( a.into(), b.into(), + self.alias_relate_direction(), ))]); } + + /// Relation direction emitted for `AliasEq` predicates + fn alias_relate_direction(&self) -> ty::AliasRelationDirection; } fn int_unification_error<'tcx>( diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index c92a74b6241a6..38002357cde35 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -210,4 +210,8 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> { fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.fields.register_obligations(obligations); } + + fn alias_relate_direction(&self) -> ty::AliasRelationDirection { + ty::AliasRelationDirection::Equate + } } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 5c12351226aa5..6395c4d4b2078 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -155,4 +155,9 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.fields.register_obligations(obligations); } + + fn alias_relate_direction(&self) -> ty::AliasRelationDirection { + // FIXME(deferred_projection_equality): This isn't right, I think? + ty::AliasRelationDirection::Equate + } } diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index dbef42db8f1bf..98cbd4c561c52 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -155,4 +155,9 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.fields.register_obligations(obligations) } + + fn alias_relate_direction(&self) -> ty::AliasRelationDirection { + // FIXME(deferred_projection_equality): This isn't right, I think? + ty::AliasRelationDirection::Equate + } } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 573cd91a2a2a6..216d2965da761 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -777,6 +777,16 @@ where fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.delegate.register_obligations(obligations); } + + fn alias_relate_direction(&self) -> ty::AliasRelationDirection { + match self.ambient_variance { + ty::Variance::Covariant => ty::AliasRelationDirection::Subtype, + ty::Variance::Contravariant => ty::AliasRelationDirection::Supertype, + ty::Variance::Invariant => ty::AliasRelationDirection::Equate, + // FIXME(deferred_projection_equality): Implement this when we trigger it + ty::Variance::Bivariant => unreachable!(), + } + } } /// When we encounter a binder like `for<..> fn(..)`, we actually have diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 230cadb11842e..fc73ca7606d23 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -236,4 +236,8 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> { fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.fields.register_obligations(obligations); } + + fn alias_relate_direction(&self) -> ty::AliasRelationDirection { + ty::AliasRelationDirection::Subtype + } } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 91241ff404f4c..1ae47fddccc1a 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -288,7 +288,7 @@ impl FlagComputation { self.add_ty(ty); } ty::PredicateKind::Ambiguous => {} - ty::PredicateKind::AliasEq(t1, t2) => { + ty::PredicateKind::AliasEq(t1, t2, _) => { self.add_term(t1); self.add_term(t2); } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d383a41320819..d1e268f49c4b2 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -640,7 +640,25 @@ pub enum PredicateKind<'tcx> { /// This predicate requires two terms to be equal to eachother. /// /// Only used for new solver - AliasEq(Term<'tcx>, Term<'tcx>), + AliasEq(Term<'tcx>, Term<'tcx>, AliasRelationDirection), +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] +#[derive(HashStable, Debug)] +pub enum AliasRelationDirection { + Equate, + Subtype, + Supertype, +} + +impl AliasRelationDirection { + pub fn invert(self) -> Self { + match self { + AliasRelationDirection::Equate => AliasRelationDirection::Equate, + AliasRelationDirection::Subtype => AliasRelationDirection::Supertype, + AliasRelationDirection::Supertype => AliasRelationDirection::Subtype, + } + } } /// The crate outlives map is computed during typeck and contains the @@ -976,11 +994,11 @@ impl<'tcx> Term<'tcx> { } } - /// This function returns `None` for `AliasKind::Opaque`. + /// This function returns the inner `AliasTy` if this term is a projection. /// /// FIXME: rename `AliasTy` to `AliasTerm` and make sure we correctly /// deal with constants. - pub fn to_alias_term_no_opaque(&self, tcx: TyCtxt<'tcx>) -> Option> { + pub fn to_projection_term(&self, tcx: TyCtxt<'tcx>) -> Option> { match self.unpack() { TermKind::Ty(ty) => match ty.kind() { ty::Alias(kind, alias_ty) => match kind { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index fffdbfc9660bb..e96856231cec4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2847,7 +2847,8 @@ define_print_and_forward_display! { p!("the type `", print(ty), "` is found in the environment") } ty::PredicateKind::Ambiguous => p!("ambiguous"), - ty::PredicateKind::AliasEq(t1, t2) => p!(print(t1), " == ", print(t2)), + // TODO + ty::PredicateKind::AliasEq(t1, t2, _) => p!(print(t1), " == ", print(t2)), } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index ef643531bb288..92a2b4b18dd6a 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -177,7 +177,8 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { write!(f, "TypeWellFormedFromEnv({:?})", ty) } ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"), - ty::PredicateKind::AliasEq(t1, t2) => write!(f, "AliasEq({t1:?}, {t2:?})"), + // TODO + ty::PredicateKind::AliasEq(t1, t2, _) => write!(f, "AliasEq({t1:?}, {t2:?})"), } } } @@ -250,6 +251,7 @@ TrivialTypeTraversalAndLiftImpls! { crate::ty::AssocItem, crate::ty::AssocKind, crate::ty::AliasKind, + crate::ty::AliasRelationDirection, crate::ty::Placeholder, crate::ty::Placeholder, crate::ty::ClosureKind, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index d884ebd9acc73..fda9ef008d715 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -180,7 +180,7 @@ where | ty::PredicateKind::ConstEquate(_, _) | ty::PredicateKind::TypeWellFormedFromEnv(_) | ty::PredicateKind::Ambiguous - | ty::PredicateKind::AliasEq(_, _) => bug!("unexpected predicate: {:?}", predicate), + | ty::PredicateKind::AliasEq(..) => bug!("unexpected predicate: {:?}", predicate), } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 9541292235795..106a989b22f61 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -223,8 +223,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } - ty::PredicateKind::AliasEq(lhs, rhs) => { - self.compute_alias_eq_goal(Goal { param_env, predicate: (lhs, rhs) }) + ty::PredicateKind::AliasEq(lhs, rhs, direction) => { + self.compute_alias_eq_goal(Goal { param_env, predicate: (lhs, rhs, direction) }) } } } else { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 38120b9760f3d..a9c9e5761a86d 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -73,7 +73,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { MismatchedProjectionTypes { err: TypeError::Mismatch }, ) } - ty::PredicateKind::AliasEq(_, _) => { + ty::PredicateKind::AliasEq(_, _, _) => { FulfillmentErrorCode::CodeProjectionError( MismatchedProjectionTypes { err: TypeError::Mismatch }, ) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 606c2eaa51051..48ef089a7b2ec 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -158,13 +158,35 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self), ret)] fn compute_alias_eq_goal( &mut self, - goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>)>, + goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>, ) -> QueryResult<'tcx> { let tcx = self.tcx(); - let evaluate_normalizes_to = |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other| { + let evaluate_normalizes_to = |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other, direction| { debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other); - let r = ecx.probe(|ecx| { + let result = ecx.probe(|ecx| { + let other = match direction { + // This is purely an optimization. + ty::AliasRelationDirection::Equate => other, + + ty::AliasRelationDirection::Subtype | ty::AliasRelationDirection::Supertype => { + let fresh = ecx.next_term_infer_of_kind(other); + let (sub, sup) = if direction == ty::AliasRelationDirection::Subtype { + (fresh, other) + } else { + (other, fresh) + }; + ecx.add_goals( + ecx.infcx + .at(&ObligationCause::dummy(), goal.param_env) + .sub(DefineOpaqueTypes::No, sub, sup)? + .into_obligations() + .into_iter() + .map(|o| o.into()), + ); + fresh + } + }; ecx.add_goal(goal.with( tcx, ty::Binder::dummy(ty::ProjectionPredicate { @@ -174,37 +196,64 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { )); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }); - debug!("evaluate_normalizes_to(..) -> {:?}", r); - r + debug!("evaluate_normalizes_to({alias}, {other}, {direction:?}) -> {result:?}"); + result }; - if goal.predicate.0.is_infer() || goal.predicate.1.is_infer() { + let (lhs, rhs, direction) = goal.predicate; + + if lhs.is_infer() || rhs.is_infer() { bug!( "`AliasEq` goal with an infer var on lhs or rhs which should have been instantiated" ); } - match ( - goal.predicate.0.to_alias_term_no_opaque(tcx), - goal.predicate.1.to_alias_term_no_opaque(tcx), - ) { + match (lhs.to_projection_term(tcx), rhs.to_projection_term(tcx)) { (None, None) => bug!("`AliasEq` goal without an alias on either lhs or rhs"), - (Some(alias), None) => evaluate_normalizes_to(self, alias, goal.predicate.1), - (None, Some(alias)) => evaluate_normalizes_to(self, alias, goal.predicate.0), - (Some(alias_lhs), Some(alias_rhs)) => { - debug!("compute_alias_eq_goal: both sides are aliases"); - let mut candidates = Vec::with_capacity(3); + // RHS is not a projection, only way this is true is if LHS normalizes-to RHS + (Some(alias_lhs), None) => evaluate_normalizes_to(self, alias_lhs, rhs, direction), - // Evaluate all 3 potential candidates for the alias' being equal - candidates.push(evaluate_normalizes_to(self, alias_lhs, goal.predicate.1)); - candidates.push(evaluate_normalizes_to(self, alias_rhs, goal.predicate.0)); - candidates.push(self.probe(|ecx| { - debug!("compute_alias_eq_goal: alias defids are equal, equating substs"); - ecx.eq(goal.param_env, alias_lhs, alias_rhs)?; - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - })); + // LHS is not a projection, only way this is true is if RHS normalizes-to LHS + (None, Some(alias_rhs)) => { + evaluate_normalizes_to(self, alias_rhs, lhs, direction.invert()) + } + (Some(alias_lhs), Some(alias_rhs)) => { + debug!("compute_alias_eq_goal: both sides are aliases"); + + let candidates = vec![ + // LHS normalizes-to RHS + evaluate_normalizes_to(self, alias_lhs, rhs, direction), + // RHS normalizes-to RHS + evaluate_normalizes_to(self, alias_rhs, lhs, direction.invert()), + // Relate via substs + self.probe(|ecx| { + debug!("compute_alias_eq_goal: alias defids are equal, equating substs"); + + ecx.add_goals( + match direction { + ty::AliasRelationDirection::Equate => ecx + .infcx + .at(&ObligationCause::dummy(), goal.param_env) + .eq(DefineOpaqueTypes::No, alias_lhs, alias_rhs), + ty::AliasRelationDirection::Subtype => ecx + .infcx + .at(&ObligationCause::dummy(), goal.param_env) + .sub(DefineOpaqueTypes::No, alias_lhs, alias_rhs), + ty::AliasRelationDirection::Supertype => ecx + .infcx + .at(&ObligationCause::dummy(), goal.param_env) + .sup(DefineOpaqueTypes::No, alias_lhs, alias_rhs), + }? + .into_obligations() + .into_iter() + .map(|o| o.into()), + ); + + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }), + ]; debug!(?candidates); self.try_merge_responses(candidates.into_iter()) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs index 1174efdbfa8fa..13607b9079a75 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs @@ -92,6 +92,11 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> { } impl<'tcx> ObligationEmittingRelation<'tcx> for CollectAllMismatches<'_, 'tcx> { + fn alias_relate_direction(&self) -> ty::AliasRelationDirection { + // FIXME(deferred_projection_equality): We really should get rid of this relation. + ty::AliasRelationDirection::Equate + } + fn register_obligations(&mut self, _obligations: PredicateObligations<'tcx>) { // FIXME(deferred_projection_equality) } diff --git a/tests/ui/traits/new-solver/alias-sub.rs b/tests/ui/traits/new-solver/alias-sub.rs new file mode 100644 index 0000000000000..30c1981a92ece --- /dev/null +++ b/tests/ui/traits/new-solver/alias-sub.rs @@ -0,0 +1,34 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Trait { + type Assoc: Sized; +} + +impl Trait for &'static str { + type Assoc = &'static str; +} + +// Wrapper is just here to get around stupid `Sized` obligations in mir typeck +struct Wrapper(std::marker::PhantomData); +fn mk(x: T) -> Wrapper<::Assoc> { todo!() } + + +trait IsStaticStr {} +impl IsStaticStr for (&'static str,) {} +fn define(_: T) {} + +fn foo<'a, T: Trait>() { + let y = Default::default(); + + // `::Assoc <: &'a str` + // In the old solver, this would *equate* the LHS and RHS. + let _: Wrapper<&'a str> = mk(y); + + // ... then later on, we constrain `?0 = &'static str` + // but that should not mean that `'a = 'static`, because + // we should use *sub* above. + define((y,)); +} + +fn main() {} From 3a36a093ddb1c117247a8154970d5f8a5782da87 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Mar 2023 22:11:40 +0000 Subject: [PATCH 2/4] Rename AliasEq -> AliasRelate --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_analysis/src/outlives/explicit.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- compiler/rustc_infer/src/infer/combine.rs | 6 +++--- compiler/rustc_infer/src/infer/outlives/mod.rs | 2 +- compiler/rustc_infer/src/infer/projection.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 10 +++++----- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 2 +- .../rustc_trait_selection/src/solve/eval_ctxt.rs | 8 +++++--- compiler/rustc_trait_selection/src/solve/fulfill.rs | 2 +- compiler/rustc_trait_selection/src/solve/mod.rs | 12 +++++++----- .../rustc_trait_selection/src/traits/auto_trait.rs | 2 +- .../src/traits/error_reporting/mod.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/fulfill.rs | 8 ++++---- .../src/traits/object_safety.rs | 4 ++-- .../rustc_trait_selection/src/traits/select/mod.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/wf.rs | 6 +++--- compiler/rustc_traits/src/chalk/lowering.rs | 8 ++++---- compiler/rustc_traits/src/implied_outlives_bounds.rs | 4 ++-- .../rustc_traits/src/normalize_erasing_regions.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- .../clippy/clippy_utils/src/qualify_min_const_fn.rs | 2 +- 29 files changed, 57 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8a9aac14fb65f..703c845eafa28 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1335,7 +1335,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) => bug!(), }, ty::PredicateKind::WellFormed(_) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::ClosureKind(_, _, _) | ty::PredicateKind::Subtype(_) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 91c64eeec1eba..7f1e4ccc9647b 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -528,7 +528,7 @@ fn trait_predicate_kind<'tcx>( | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_)) | ty::PredicateKind::Clause(ty::Clause::Projection(_)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::WellFormed(_) | ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index 9ee6785970c46..357deb07b8f31 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -56,7 +56,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) | ty::PredicateKind::WellFormed(..) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 8455076de5634..3def97bca4789 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -666,7 +666,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) | ty::PredicateKind::WellFormed(..) | ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) // N.B., this predicate is created by breaking down a diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index b6d39341fe7cc..0eff5c956ef64 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -838,7 +838,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } }); diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index c82438f05e140..3fadc243dcd7a 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -842,7 +842,7 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) }; self.register_predicates([ty::Binder::dummy(if self.tcx().trait_solver_next() { - ty::PredicateKind::AliasEq(a.into(), b.into(), ty::AliasRelationDirection::Equate) + ty::PredicateKind::AliasRelate(a.into(), b.into(), ty::AliasRelationDirection::Equate) } else { ty::PredicateKind::ConstEquate(a, b) })]); @@ -852,14 +852,14 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { /// /// If they aren't equal then the relation doesn't hold. fn register_type_equate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { - self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasEq( + self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate( a.into(), b.into(), self.alias_relate_direction(), ))]); } - /// Relation direction emitted for `AliasEq` predicates + /// Relation direction emitted for `AliasRelate` predicates fn alias_relate_direction(&self) -> ty::AliasRelationDirection; } diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 83f3d5a74fb48..048dad3a48bc2 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -22,7 +22,7 @@ pub fn explicit_outlives_bounds<'tcx>( ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::WellFormed(..) diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index f795047709e40..fa6529dfa93ec 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -26,7 +26,7 @@ impl<'tcx> InferCtxt<'tcx> { // completely change the normalization routine with the new solver. // // The new solver correctly handles projection equality so this hack - // is not necessary. if re-enabled it should emit `PredicateKind::AliasEq` + // is not necessary. if re-enabled it should emit `PredicateKind::AliasRelate` // not `PredicateKind::Clause(Clause::Projection(..))` as in the new solver // `Projection` is used as `normalizes-to` which will fail for `::Assoc eq ?0`. return projection_ty.to_ty(self.tcx); diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index c07ff51657994..0d2faeba5fc0f 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -293,7 +293,7 @@ impl<'tcx> Elaborator<'tcx> { // Nothing to elaborate } ty::PredicateKind::Ambiguous => {} - ty::PredicateKind::AliasEq(..) => { + ty::PredicateKind::AliasRelate(..) => { // No } ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 8af1a663ef5e3..f8dd8299312d8 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1601,7 +1601,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { // Ignore projections, as they can only be global // if the trait bound is global Clause(Clause::Projection(..)) | - AliasEq(..) | + AliasRelate(..) | // Ignore bounds that a user can't type WellFormed(..) | ObjectSafe(..) | diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 1ae47fddccc1a..5a6ee1238112c 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -288,7 +288,7 @@ impl FlagComputation { self.add_ty(ty); } ty::PredicateKind::Ambiguous => {} - ty::PredicateKind::AliasEq(t1, t2, _) => { + ty::PredicateKind::AliasRelate(t1, t2, _) => { self.add_term(t1); self.add_term(t2); } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d1e268f49c4b2..4ab3df917e34c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -543,7 +543,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Clause(Clause::TypeOutlives(_)) | PredicateKind::Clause(Clause::Projection(_)) | PredicateKind::Clause(Clause::ConstArgHasType(..)) - | PredicateKind::AliasEq(..) + | PredicateKind::AliasRelate(..) | PredicateKind::ObjectSafe(_) | PredicateKind::ClosureKind(_, _, _) | PredicateKind::Subtype(_) @@ -640,7 +640,7 @@ pub enum PredicateKind<'tcx> { /// This predicate requires two terms to be equal to eachother. /// /// Only used for new solver - AliasEq(Term<'tcx>, Term<'tcx>, AliasRelationDirection), + AliasRelate(Term<'tcx>, Term<'tcx>, AliasRelationDirection), } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] @@ -1224,7 +1224,7 @@ impl<'tcx> Predicate<'tcx> { PredicateKind::Clause(Clause::Trait(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Projection(..)) | PredicateKind::Clause(Clause::ConstArgHasType(..)) - | PredicateKind::AliasEq(..) + | PredicateKind::AliasRelate(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) @@ -1245,7 +1245,7 @@ impl<'tcx> Predicate<'tcx> { PredicateKind::Clause(Clause::Projection(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(Clause::Trait(..)) | PredicateKind::Clause(Clause::ConstArgHasType(..)) - | PredicateKind::AliasEq(..) + | PredicateKind::AliasRelate(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) @@ -1267,7 +1267,7 @@ impl<'tcx> Predicate<'tcx> { PredicateKind::Clause(Clause::Trait(..)) | PredicateKind::Clause(Clause::ConstArgHasType(..)) | PredicateKind::Clause(Clause::Projection(..)) - | PredicateKind::AliasEq(..) + | PredicateKind::AliasRelate(..) | PredicateKind::Subtype(..) | PredicateKind::Coerce(..) | PredicateKind::Clause(Clause::RegionOutlives(..)) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e96856231cec4..ad5c9d93b4704 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2848,7 +2848,7 @@ define_print_and_forward_display! { } ty::PredicateKind::Ambiguous => p!("ambiguous"), // TODO - ty::PredicateKind::AliasEq(t1, t2, _) => p!(print(t1), " == ", print(t2)), + ty::PredicateKind::AliasRelate(t1, t2, _) => p!(print(t1), " == ", print(t2)), } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 92a2b4b18dd6a..ad5f33d34dc2c 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -178,7 +178,7 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { } ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"), // TODO - ty::PredicateKind::AliasEq(t1, t2, _) => write!(f, "AliasEq({t1:?}, {t2:?})"), + ty::PredicateKind::AliasRelate(t1, t2, _) => write!(f, "AliasRelate({t1:?}, {t2:?})"), } } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index fda9ef008d715..3be0160d56173 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -180,7 +180,7 @@ where | ty::PredicateKind::ConstEquate(_, _) | ty::PredicateKind::TypeWellFormedFromEnv(_) | ty::PredicateKind::Ambiguous - | ty::PredicateKind::AliasEq(..) => bug!("unexpected predicate: {:?}", predicate), + | ty::PredicateKind::AliasRelate(..) => bug!("unexpected predicate: {:?}", predicate), } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 106a989b22f61..4cfea28475732 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -223,9 +223,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } - ty::PredicateKind::AliasEq(lhs, rhs, direction) => { - self.compute_alias_eq_goal(Goal { param_env, predicate: (lhs, rhs, direction) }) - } + ty::PredicateKind::AliasRelate(lhs, rhs, direction) => self + .compute_alias_relate_goal(Goal { + param_env, + predicate: (lhs, rhs, direction), + }), } } else { let kind = self.infcx.instantiate_binder_with_placeholders(kind); diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index a9c9e5761a86d..01f171762ab67 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -73,7 +73,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { MismatchedProjectionTypes { err: TypeError::Mismatch }, ) } - ty::PredicateKind::AliasEq(_, _, _) => { + ty::PredicateKind::AliasRelate(_, _, _) => { FulfillmentErrorCode::CodeProjectionError( MismatchedProjectionTypes { err: TypeError::Mismatch }, ) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 48ef089a7b2ec..5cda9da3c5a31 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -156,7 +156,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } #[instrument(level = "debug", skip(self), ret)] - fn compute_alias_eq_goal( + fn compute_alias_relate_goal( &mut self, goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>, ) -> QueryResult<'tcx> { @@ -204,12 +204,12 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { if lhs.is_infer() || rhs.is_infer() { bug!( - "`AliasEq` goal with an infer var on lhs or rhs which should have been instantiated" + "`AliasRelate` goal with an infer var on lhs or rhs which should have been instantiated" ); } match (lhs.to_projection_term(tcx), rhs.to_projection_term(tcx)) { - (None, None) => bug!("`AliasEq` goal without an alias on either lhs or rhs"), + (None, None) => bug!("`AliasRelate` goal without an alias on either lhs or rhs"), // RHS is not a projection, only way this is true is if LHS normalizes-to RHS (Some(alias_lhs), None) => evaluate_normalizes_to(self, alias_lhs, rhs, direction), @@ -220,7 +220,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } (Some(alias_lhs), Some(alias_rhs)) => { - debug!("compute_alias_eq_goal: both sides are aliases"); + debug!("compute_alias_relate_goal: both sides are aliases"); let candidates = vec![ // LHS normalizes-to RHS @@ -229,7 +229,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { evaluate_normalizes_to(self, alias_rhs, lhs, direction.invert()), // Relate via substs self.probe(|ecx| { - debug!("compute_alias_eq_goal: alias defids are equal, equating substs"); + debug!( + "compute_alias_relate_goal: alias defids are equal, equating substs" + ); ecx.add_goals( match direction { diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index dbf6775afc2fc..6b3a59b1ed545 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -832,7 +832,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // the `ParamEnv`. ty::PredicateKind::WellFormed(..) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 41ffaeeac1c11..617d53b609dbc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1276,9 +1276,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { "TypeWellFormedFromEnv predicate should only exist in the environment" ), - ty::PredicateKind::AliasEq(..) => span_bug!( + ty::PredicateKind::AliasRelate(..) => span_bug!( span, - "AliasEq predicate should never be the predicate cause of a SelectionError" + "AliasRelate predicate should never be the predicate cause of a SelectionError" ), ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 23754480fcfb0..07e31e87bfb46 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -361,8 +361,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } - ty::PredicateKind::AliasEq(..) => { - bug!("AliasEq is only used for new solver") + ty::PredicateKind::AliasRelate(..) => { + bug!("AliasRelate is only used for new solver") } }, Some(pred) => match pred { @@ -630,8 +630,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } - ty::PredicateKind::AliasEq(..) => { - bug!("AliasEq is only used for new solver") + ty::PredicateKind::AliasRelate(..) => { + bug!("AliasRelate is only used for new solver") } ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq( diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 038f8964471f5..5d2af5ff33c8f 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -335,7 +335,7 @@ fn predicate_references_self<'tcx>( has_self_ty(&ty.into()).then_some(sp) } - ty::PredicateKind::AliasEq(..) => bug!("`AliasEq` not allowed as assumption"), + ty::PredicateKind::AliasRelate(..) => bug!("`AliasRelate` not allowed as assumption"), ty::PredicateKind::WellFormed(..) | ty::PredicateKind::ObjectSafe(..) @@ -395,7 +395,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => false, } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b8758ad93231d..bffefdf359ad5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -977,8 +977,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for chalk") } - ty::PredicateKind::AliasEq(..) => { - bug!("AliasEq is only used for new solver") + ty::PredicateKind::AliasRelate(..) => { + bug!("AliasRelate is only used for new solver") } ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index d498af359c584..ec5bd982a3c98 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -191,8 +191,8 @@ pub fn predicate_obligations<'tcx>( ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } - ty::PredicateKind::AliasEq(..) => { - bug!("We should only wf check where clauses and `AliasEq` is not a `Clause`") + ty::PredicateKind::AliasRelate(..) => { + bug!("We should only wf check where clauses and `AliasRelate` is not a `Clause`") } } @@ -936,7 +936,7 @@ pub(crate) fn required_region_bounds<'tcx>( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate( ref t, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 60e22d1001c81..0e9bccba8d4c5 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -119,7 +119,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi // some of these in terms of chalk operations. ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::Ambiguous @@ -652,7 +652,7 @@ impl<'tcx> LowerInto<'tcx, Option None, ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) @@ -787,7 +787,7 @@ impl<'tcx> LowerInto<'tcx, Option None, ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index ddd4ca1436c09..f5bba14d2fb9c 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -86,7 +86,7 @@ fn compute_implied_outlives_bounds<'tcx>( if obligation.predicate.has_non_region_infer() { match obligation.predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Projection(..)) - | ty::PredicateKind::AliasEq(..) => { + | ty::PredicateKind::AliasRelate(..) => { ocx.register_obligation(obligation.clone()); } _ => {} @@ -110,7 +110,7 @@ fn compute_implied_outlives_bounds<'tcx>( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => {} // We need to search through *all* WellFormed predicates diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index f0597f19225c8..126a494f34fd6 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -61,7 +61,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::WellFormed(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e3e5454ef5443..44dfff0efbe94 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -324,7 +324,7 @@ pub(crate) fn clean_predicate<'tcx>( ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None, ty::PredicateKind::Subtype(..) - | ty::PredicateKind::AliasEq(..) + | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ClosureKind(..) diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 24403e8b6f347..58f7742ab8764 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -37,7 +37,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, - ty::PredicateKind::AliasEq(..) => panic!("alias eq predicate on function: {predicate:#?}"), + ty::PredicateKind::AliasRelate(..) => panic!("alias relate predicate on function: {predicate:#?}"), ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {predicate:#?}"), ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"), ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"), From f6fd7546804dd25d4996196dbc9653bde2b4a131 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Mar 2023 22:20:54 +0000 Subject: [PATCH 3/4] Printing alias-relate goals correctly --- compiler/rustc_middle/src/ty/mod.rs | 10 ++++++++++ compiler/rustc_middle/src/ty/print/pretty.rs | 3 +-- compiler/rustc_middle/src/ty/structural_impls.rs | 5 +++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4ab3df917e34c..23139e6be7abe 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -661,6 +661,16 @@ impl AliasRelationDirection { } } +impl std::fmt::Display for AliasRelationDirection { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AliasRelationDirection::Equate => write!(f, " == "), + AliasRelationDirection::Subtype => write!(f, " <: "), + AliasRelationDirection::Supertype => write!(f, " :> "), + } + } +} + /// The crate outlives map is computed during typeck and contains the /// outlives of every item in the local crate. You should not use it /// directly, because to do so will make your pass dependent on the diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ad5c9d93b4704..e9f8f2e586592 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2847,8 +2847,7 @@ define_print_and_forward_display! { p!("the type `", print(ty), "` is found in the environment") } ty::PredicateKind::Ambiguous => p!("ambiguous"), - // TODO - ty::PredicateKind::AliasRelate(t1, t2, _) => p!(print(t1), " == ", print(t2)), + ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)), } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index ad5f33d34dc2c..c6bb814679586 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -177,8 +177,9 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { write!(f, "TypeWellFormedFromEnv({:?})", ty) } ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"), - // TODO - ty::PredicateKind::AliasRelate(t1, t2, _) => write!(f, "AliasRelate({t1:?}, {t2:?})"), + ty::PredicateKind::AliasRelate(t1, t2, dir) => { + write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})") + } } } } From 244cdaa457d80b3e1ef90795a48833f948ac0db9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Mar 2023 16:58:51 +0000 Subject: [PATCH 4/4] Remove AliasRelationDirection::Supertype --- compiler/rustc_infer/src/infer/combine.rs | 12 +- .../rustc_infer/src/infer/nll_relate/mod.rs | 30 ++++- compiler/rustc_middle/src/ty/mod.rs | 12 -- .../src/solve/eval_ctxt.rs | 19 +++ .../rustc_trait_selection/src/solve/mod.rs | 117 ++++++++---------- 5 files changed, 99 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 3fadc243dcd7a..88a28e26005d6 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -128,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> { (_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _) if self.tcx.trait_solver_next() => { - relation.register_type_equate_obligation(a, b); + relation.register_type_relate_obligation(a, b); Ok(a) } @@ -848,10 +848,9 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { })]); } - /// Register an obligation that both types must be equal to each other. - /// - /// If they aren't equal then the relation doesn't hold. - fn register_type_equate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + /// Register an obligation that both types must be related to each other according to + /// the [`ty::AliasRelationDirection`] given by [`ObligationEmittingRelation::alias_relate_direction`] + fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate( a.into(), b.into(), @@ -859,7 +858,8 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { ))]); } - /// Relation direction emitted for `AliasRelate` predicates + /// Relation direction emitted for `AliasRelate` predicates, corresponding to the direction + /// of the relation. fn alias_relate_direction(&self) -> ty::AliasRelationDirection; } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 216d2965da761..61d1b69be5581 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -779,13 +779,31 @@ where } fn alias_relate_direction(&self) -> ty::AliasRelationDirection { - match self.ambient_variance { - ty::Variance::Covariant => ty::AliasRelationDirection::Subtype, - ty::Variance::Contravariant => ty::AliasRelationDirection::Supertype, - ty::Variance::Invariant => ty::AliasRelationDirection::Equate, - // FIXME(deferred_projection_equality): Implement this when we trigger it + unreachable!("manually overridden to handle ty::Variance::Contravariant ambient variance") + } + + fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + self.register_predicates([ty::Binder::dummy(match self.ambient_variance { + ty::Variance::Covariant => ty::PredicateKind::AliasRelate( + a.into(), + b.into(), + ty::AliasRelationDirection::Subtype, + ), + // a :> b is b <: a + ty::Variance::Contravariant => ty::PredicateKind::AliasRelate( + b.into(), + a.into(), + ty::AliasRelationDirection::Subtype, + ), + ty::Variance::Invariant => ty::PredicateKind::AliasRelate( + a.into(), + b.into(), + ty::AliasRelationDirection::Equate, + ), + // FIXME(deferred_projection_equality): Implement this when we trigger it. + // Probably just need to do nothing here. ty::Variance::Bivariant => unreachable!(), - } + })]); } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 23139e6be7abe..7ea242f55b0f1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -648,17 +648,6 @@ pub enum PredicateKind<'tcx> { pub enum AliasRelationDirection { Equate, Subtype, - Supertype, -} - -impl AliasRelationDirection { - pub fn invert(self) -> Self { - match self { - AliasRelationDirection::Equate => AliasRelationDirection::Equate, - AliasRelationDirection::Subtype => AliasRelationDirection::Supertype, - AliasRelationDirection::Supertype => AliasRelationDirection::Subtype, - } - } } impl std::fmt::Display for AliasRelationDirection { @@ -666,7 +655,6 @@ impl std::fmt::Display for AliasRelationDirection { match self { AliasRelationDirection::Equate => write!(f, " == "), AliasRelationDirection::Subtype => write!(f, " <: "), - AliasRelationDirection::Supertype => write!(f, " :> "), } } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 4cfea28475732..75b304cce4e09 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -459,6 +459,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }) } + #[instrument(level = "debug", skip(self, param_env), ret)] + pub(super) fn sub>( + &mut self, + param_env: ty::ParamEnv<'tcx>, + sub: T, + sup: T, + ) -> Result<(), NoSolution> { + self.infcx + .at(&ObligationCause::dummy(), param_env) + .sub(DefineOpaqueTypes::No, sub, sup) + .map(|InferOk { value: (), obligations }| { + self.add_goals(obligations.into_iter().map(|o| o.into())); + }) + .map_err(|e| { + debug!(?e, "failed to subtype"); + NoSolution + }) + } + /// Equates two values returning the nested goals without adding them /// to the nested goals of the `EvalCtxt`. /// diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 5cda9da3c5a31..4c87d36ca0dc1 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -17,7 +17,6 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; -use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_infer::traits::query::NoSolution; use rustc_middle::traits::solve::{ CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraints, ExternalConstraintsData, @@ -101,11 +100,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { // That won't actually reflect in the query response, so it seems moot. self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } else { - let InferOk { value: (), obligations } = self - .infcx - .at(&ObligationCause::dummy(), goal.param_env) - .sub(DefineOpaqueTypes::No, goal.predicate.a, goal.predicate.b)?; - self.add_goals(obligations.into_iter().map(|pred| pred.into())); + self.sub(goal.param_env, goal.predicate.a, goal.predicate.b)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } @@ -161,44 +156,41 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>, ) -> QueryResult<'tcx> { let tcx = self.tcx(); - - let evaluate_normalizes_to = |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other, direction| { - debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other); - let result = ecx.probe(|ecx| { - let other = match direction { - // This is purely an optimization. - ty::AliasRelationDirection::Equate => other, - - ty::AliasRelationDirection::Subtype | ty::AliasRelationDirection::Supertype => { - let fresh = ecx.next_term_infer_of_kind(other); - let (sub, sup) = if direction == ty::AliasRelationDirection::Subtype { - (fresh, other) - } else { - (other, fresh) - }; - ecx.add_goals( - ecx.infcx - .at(&ObligationCause::dummy(), goal.param_env) - .sub(DefineOpaqueTypes::No, sub, sup)? - .into_obligations() - .into_iter() - .map(|o| o.into()), - ); - fresh - } - }; - ecx.add_goal(goal.with( - tcx, - ty::Binder::dummy(ty::ProjectionPredicate { - projection_ty: alias, - term: other, - }), - )); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }); - debug!("evaluate_normalizes_to({alias}, {other}, {direction:?}) -> {result:?}"); - result - }; + // We may need to invert the alias relation direction if dealing an alias on the RHS. + enum Invert { + No, + Yes, + } + let evaluate_normalizes_to = + |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other, direction, invert| { + debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other); + let result = ecx.probe(|ecx| { + let other = match direction { + // This is purely an optimization. + ty::AliasRelationDirection::Equate => other, + + ty::AliasRelationDirection::Subtype => { + let fresh = ecx.next_term_infer_of_kind(other); + let (sub, sup) = match invert { + Invert::No => (fresh, other), + Invert::Yes => (other, fresh), + }; + ecx.sub(goal.param_env, sub, sup)?; + fresh + } + }; + ecx.add_goal(goal.with( + tcx, + ty::Binder::dummy(ty::ProjectionPredicate { + projection_ty: alias, + term: other, + }), + )); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }); + debug!("evaluate_normalizes_to({alias}, {other}, {direction:?}) -> {result:?}"); + result + }; let (lhs, rhs, direction) = goal.predicate; @@ -212,11 +204,13 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { (None, None) => bug!("`AliasRelate` goal without an alias on either lhs or rhs"), // RHS is not a projection, only way this is true is if LHS normalizes-to RHS - (Some(alias_lhs), None) => evaluate_normalizes_to(self, alias_lhs, rhs, direction), + (Some(alias_lhs), None) => { + evaluate_normalizes_to(self, alias_lhs, rhs, direction, Invert::No) + } // LHS is not a projection, only way this is true is if RHS normalizes-to LHS (None, Some(alias_rhs)) => { - evaluate_normalizes_to(self, alias_rhs, lhs, direction.invert()) + evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes) } (Some(alias_lhs), Some(alias_rhs)) => { @@ -224,34 +218,23 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { let candidates = vec![ // LHS normalizes-to RHS - evaluate_normalizes_to(self, alias_lhs, rhs, direction), + evaluate_normalizes_to(self, alias_lhs, rhs, direction, Invert::No), // RHS normalizes-to RHS - evaluate_normalizes_to(self, alias_rhs, lhs, direction.invert()), + evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes), // Relate via substs self.probe(|ecx| { debug!( "compute_alias_relate_goal: alias defids are equal, equating substs" ); - ecx.add_goals( - match direction { - ty::AliasRelationDirection::Equate => ecx - .infcx - .at(&ObligationCause::dummy(), goal.param_env) - .eq(DefineOpaqueTypes::No, alias_lhs, alias_rhs), - ty::AliasRelationDirection::Subtype => ecx - .infcx - .at(&ObligationCause::dummy(), goal.param_env) - .sub(DefineOpaqueTypes::No, alias_lhs, alias_rhs), - ty::AliasRelationDirection::Supertype => ecx - .infcx - .at(&ObligationCause::dummy(), goal.param_env) - .sup(DefineOpaqueTypes::No, alias_lhs, alias_rhs), - }? - .into_obligations() - .into_iter() - .map(|o| o.into()), - ); + match direction { + ty::AliasRelationDirection::Equate => { + ecx.eq(goal.param_env, alias_lhs, alias_rhs)?; + } + ty::AliasRelationDirection::Subtype => { + ecx.sub(goal.param_env, alias_lhs, alias_rhs)?; + } + } ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }),