Auto merge of #118725 - lcnr:normalizes-to-projection-split-3, r=BoxyUwU
split `NormalizesTo` out of `Projection` 3 third attempt at #112658. Rebasing #116262 is very annoying, so I am doing it again from scratch. We should now be able to merge it without regressing anything as we handle occurs check failures involving aliases correctly since #117088. see https://hackmd.io/ktEL8knTSYmtdfrMMnA-Hg fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/1 r? `@compiler-errors`
This commit is contained in:
commit
21982a4383
39 changed files with 310 additions and 189 deletions
|
@ -92,7 +92,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
self.add_goal(Goal::new(
|
||||
self.tcx(),
|
||||
param_env,
|
||||
ty::ProjectionPredicate { projection_ty: alias, term },
|
||||
ty::NormalizesTo { alias, term },
|
||||
));
|
||||
self.try_evaluate_added_goals()?;
|
||||
Ok(Some(self.resolve_vars_if_possible(term)))
|
||||
|
@ -109,11 +109,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
opaque: ty::AliasTy<'tcx>,
|
||||
term: ty::Term<'tcx>,
|
||||
) -> QueryResult<'tcx> {
|
||||
self.add_goal(Goal::new(
|
||||
self.tcx(),
|
||||
param_env,
|
||||
ty::ProjectionPredicate { projection_ty: opaque, term },
|
||||
));
|
||||
self.add_goal(Goal::new(self.tcx(), param_env, ty::NormalizesTo { alias: opaque, term }));
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
|
||||
|
|
|
@ -352,15 +352,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
num_steps: usize,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
let &ty::Alias(_, projection_ty) = goal.predicate.self_ty().kind() else { return };
|
||||
let &ty::Alias(_, alias) = goal.predicate.self_ty().kind() else { return };
|
||||
|
||||
candidates.extend(self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
|
||||
if tcx.recursion_limit().value_within_limit(num_steps) {
|
||||
let normalized_ty = ecx.next_ty_infer();
|
||||
let normalizes_to_goal = goal.with(
|
||||
tcx,
|
||||
ty::ProjectionPredicate { projection_ty, term: normalized_ty.into() },
|
||||
);
|
||||
let normalizes_to_goal =
|
||||
goal.with(tcx, ty::NormalizesTo { alias, term: normalized_ty.into() });
|
||||
ecx.add_goal(normalizes_to_goal);
|
||||
if let Err(NoSolution) = ecx.try_evaluate_added_goals() {
|
||||
debug!("self type normalization failed");
|
||||
|
|
|
@ -69,8 +69,8 @@ impl<'a, 'tcx> Canonicalizer<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let value = value.fold_with(&mut canonicalizer);
|
||||
assert!(!value.has_infer());
|
||||
assert!(!value.has_placeholders());
|
||||
assert!(!value.has_infer(), "unexpected infer in {value:?}");
|
||||
assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
|
||||
|
||||
let (max_universe, variables) = canonicalizer.finalize();
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ pub(super) struct NestedGoals<'tcx> {
|
|||
/// with a fresh inference variable when we evaluate this goal. That can result
|
||||
/// in a trait solver cycle. This would currently result in overflow but can be
|
||||
/// can be unsound with more powerful coinduction in the future.
|
||||
pub(super) normalizes_to_hack_goal: Option<Goal<'tcx, ty::ProjectionPredicate<'tcx>>>,
|
||||
pub(super) normalizes_to_hack_goal: Option<Goal<'tcx, ty::NormalizesTo<'tcx>>>,
|
||||
/// The rest of the goals which have not yet processed or remain ambiguous.
|
||||
pub(super) goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||
}
|
||||
|
@ -423,6 +423,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
ty::PredicateKind::ConstEquate(_, _) => {
|
||||
bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active")
|
||||
}
|
||||
ty::PredicateKind::NormalizesTo(predicate) => {
|
||||
self.compute_normalizes_to_goal(Goal { param_env, predicate })
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => self
|
||||
.compute_alias_relate_goal(Goal {
|
||||
param_env,
|
||||
|
@ -492,10 +495,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
let unconstrained_rhs = self.next_term_infer_of_kind(goal.predicate.term);
|
||||
let unconstrained_goal = goal.with(
|
||||
tcx,
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: goal.predicate.projection_ty,
|
||||
term: unconstrained_rhs,
|
||||
},
|
||||
ty::NormalizesTo { alias: goal.predicate.alias, term: unconstrained_rhs },
|
||||
);
|
||||
|
||||
let (_, certainty, instantiate_goals) = self.evaluate_goal(
|
||||
|
@ -517,9 +517,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
// looking at the "has changed" return from evaluate_goal,
|
||||
// because we expect the `unconstrained_rhs` part of the predicate
|
||||
// to have changed -- that means we actually normalized successfully!
|
||||
if goal.predicate.projection_ty
|
||||
!= self.resolve_vars_if_possible(goal.predicate.projection_ty)
|
||||
{
|
||||
if goal.predicate.alias != self.resolve_vars_if_possible(goal.predicate.alias) {
|
||||
unchanged_certainty = None;
|
||||
}
|
||||
|
||||
|
@ -589,9 +587,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
///
|
||||
/// This is the case if the `term` is an inference variable in the innermost universe
|
||||
/// and does not occur in any other part of the predicate.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
pub(super) fn term_is_fully_unconstrained(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> bool {
|
||||
let term_is_infer = match goal.predicate.term.unpack() {
|
||||
ty::TermKind::Ty(ty) => {
|
||||
|
@ -655,7 +654,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
let mut visitor = ContainsTerm { infcx: self.infcx, term: goal.predicate.term };
|
||||
|
||||
term_is_infer
|
||||
&& goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
|
||||
&& goal.predicate.alias.visit_with(&mut visitor).is_continue()
|
||||
&& goal.param_env.visit_with(&mut visitor).is_continue()
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,11 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
|||
MismatchedProjectionTypes { err: TypeError::Mismatch },
|
||||
)
|
||||
}
|
||||
ty::PredicateKind::NormalizesTo(..) => {
|
||||
FulfillmentErrorCode::CodeProjectionError(
|
||||
MismatchedProjectionTypes { err: TypeError::Mismatch },
|
||||
)
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(_, _, _) => {
|
||||
FulfillmentErrorCode::CodeProjectionError(
|
||||
MismatchedProjectionTypes { err: TypeError::Mismatch },
|
||||
|
|
|
@ -35,6 +35,7 @@ mod eval_ctxt;
|
|||
mod fulfill;
|
||||
pub mod inspect;
|
||||
mod normalize;
|
||||
mod normalizes_to;
|
||||
mod project_goals;
|
||||
mod search_graph;
|
||||
mod trait_goals;
|
||||
|
@ -216,7 +217,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
|
||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn set_normalizes_to_hack_goal(&mut self, goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>) {
|
||||
fn set_normalizes_to_hack_goal(&mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>) {
|
||||
assert!(
|
||||
self.nested_goals.normalizes_to_hack_goal.is_none(),
|
||||
"attempted to set the projection eq hack goal when one already exists"
|
||||
|
@ -310,17 +311,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
return None;
|
||||
}
|
||||
|
||||
let ty::Alias(kind, projection_ty) = *ty.kind() else {
|
||||
let ty::Alias(kind, alias) = *ty.kind() else {
|
||||
return Some(ty);
|
||||
};
|
||||
|
||||
// We do no always define opaque types eagerly to allow non-defining uses in the defining scope.
|
||||
if let (DefineOpaqueTypes::No, ty::AliasKind::Opaque) = (define_opaque_types, kind) {
|
||||
if let Some(def_id) = projection_ty.def_id.as_local() {
|
||||
if let Some(def_id) = alias.def_id.as_local() {
|
||||
if self
|
||||
.unify_existing_opaque_tys(
|
||||
param_env,
|
||||
OpaqueTypeKey { def_id, args: projection_ty.args },
|
||||
OpaqueTypeKey { def_id, args: alias.args },
|
||||
self.next_ty_infer(),
|
||||
)
|
||||
.is_empty()
|
||||
|
@ -335,7 +336,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
let normalizes_to_goal = Goal::new(
|
||||
this.tcx(),
|
||||
param_env,
|
||||
ty::ProjectionPredicate { projection_ty, term: normalized_ty.into() },
|
||||
ty::NormalizesTo { alias, term: normalized_ty.into() },
|
||||
);
|
||||
this.add_goal(normalizes_to_goal);
|
||||
this.try_evaluate_added_goals()?;
|
||||
|
|
|
@ -76,7 +76,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
|
|||
tcx,
|
||||
self.at.cause.clone(),
|
||||
self.at.param_env,
|
||||
ty::ProjectionPredicate { projection_ty: alias, term: new_infer_ty.into() },
|
||||
ty::NormalizesTo { alias, term: new_infer_ty.into() },
|
||||
);
|
||||
|
||||
// Do not emit an error if normalization is known to fail but instead
|
||||
|
@ -129,8 +129,8 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
|
|||
tcx,
|
||||
self.at.cause.clone(),
|
||||
self.at.param_env,
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: AliasTy::new(tcx, uv.def, uv.args),
|
||||
ty::NormalizesTo {
|
||||
alias: AliasTy::new(tcx, uv.def, uv.args),
|
||||
term: new_infer_ct.into(),
|
||||
},
|
||||
);
|
||||
|
|
|
@ -12,10 +12,10 @@ use super::EvalCtxt;
|
|||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
pub(super) fn normalize_inherent_associated_type(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let inherent = goal.predicate.projection_ty;
|
||||
let inherent = goal.predicate.alias;
|
||||
let expected = goal.predicate.term.ty().expect("inherent consts are treated separately");
|
||||
|
||||
let impl_def_id = tcx.parent(inherent.def_id);
|
|
@ -13,20 +13,20 @@ use rustc_middle::traits::solve::{
|
|||
};
|
||||
use rustc_middle::traits::BuiltinImplSource;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::ProjectionPredicate;
|
||||
use rustc_middle::ty::NormalizesTo;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
|
||||
use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};
|
||||
|
||||
mod inherent_projection;
|
||||
mod inherent;
|
||||
mod opaques;
|
||||
mod weak_types;
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
pub(super) fn compute_projection_goal(
|
||||
pub(super) fn compute_normalizes_to_goal(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
|
||||
goal: Goal<'tcx, NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let def_id = goal.predicate.def_id();
|
||||
match self.tcx().def_kind(def_id) {
|
||||
|
@ -71,16 +71,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn normalize_anon_const(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
if let Some(normalized_const) = self.try_const_eval_resolve(
|
||||
goal.param_env,
|
||||
ty::UnevaluatedConst::new(
|
||||
goal.predicate.projection_ty.def_id,
|
||||
goal.predicate.projection_ty.args,
|
||||
),
|
||||
ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args),
|
||||
self.tcx()
|
||||
.type_of(goal.predicate.projection_ty.def_id)
|
||||
.type_of(goal.predicate.alias.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const ty should not rely on other generics"),
|
||||
) {
|
||||
|
@ -92,13 +89,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||
impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
fn self_ty(self) -> Ty<'tcx> {
|
||||
self.self_ty()
|
||||
}
|
||||
|
||||
fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
|
||||
self.projection_ty.trait_ref(tcx)
|
||||
self.alias.trait_ref(tcx)
|
||||
}
|
||||
|
||||
fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||
|
@ -123,7 +120,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||
ecx.instantiate_binder_with_infer(projection_pred);
|
||||
ecx.eq(
|
||||
goal.param_env,
|
||||
goal.predicate.projection_ty,
|
||||
goal.predicate.alias,
|
||||
assumption_projection_pred.projection_ty,
|
||||
)?;
|
||||
ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)
|
||||
|
@ -132,7 +129,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||
// Add GAT where clauses from the trait's definition
|
||||
ecx.add_goals(
|
||||
tcx.predicates_of(goal.predicate.def_id())
|
||||
.instantiate_own(tcx, goal.predicate.projection_ty.args)
|
||||
.instantiate_own(tcx, goal.predicate.alias.args)
|
||||
.map(|(pred, _)| goal.with(tcx, pred)),
|
||||
);
|
||||
|
||||
|
@ -148,12 +145,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||
|
||||
fn consider_impl_candidate(
|
||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
|
||||
goal: Goal<'tcx, NormalizesTo<'tcx>>,
|
||||
impl_def_id: DefId,
|
||||
) -> Result<Candidate<'tcx>, NoSolution> {
|
||||
let tcx = ecx.tcx();
|
||||
|
||||
let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx);
|
||||
let goal_trait_ref = goal.predicate.alias.trait_ref(tcx);
|
||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
|
||||
if !drcx.args_may_unify(goal_trait_ref.args, impl_trait_ref.skip_binder().args) {
|
||||
|
@ -177,7 +174,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||
// Add GAT where clauses from the trait's definition
|
||||
ecx.add_goals(
|
||||
tcx.predicates_of(goal.predicate.def_id())
|
||||
.instantiate_own(tcx, goal.predicate.projection_ty.args)
|
||||
.instantiate_own(tcx, goal.predicate.alias.args)
|
||||
.map(|(pred, _)| goal.with(tcx, pred)),
|
||||
);
|
||||
|
||||
|
@ -202,7 +199,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||
tcx,
|
||||
guar,
|
||||
tcx.type_of(goal.predicate.def_id())
|
||||
.instantiate(tcx, goal.predicate.projection_ty.args),
|
||||
.instantiate(tcx, goal.predicate.alias.args),
|
||||
)
|
||||
.into(),
|
||||
ty::AssocKind::Type => Ty::new_error(tcx, guar).into(),
|
||||
|
@ -227,11 +224,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||
//
|
||||
// And then map these args to the args of the defining impl of `Assoc`, going
|
||||
// from `[u32, u64]` to `[u32, i32, u64]`.
|
||||
let impl_args_with_gat = goal.predicate.projection_ty.args.rebase_onto(
|
||||
tcx,
|
||||
goal_trait_ref.def_id,
|
||||
impl_args,
|
||||
);
|
||||
let impl_args_with_gat =
|
||||
goal.predicate.alias.args.rebase_onto(tcx, goal_trait_ref.def_id, impl_args);
|
||||
let args = ecx.translate_args(
|
||||
goal.param_env,
|
||||
impl_def_id,
|
|
@ -12,10 +12,10 @@ use crate::solve::{EvalCtxt, SolverMode};
|
|||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
pub(super) fn normalize_opaque_type(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let opaque_ty = goal.predicate.projection_ty;
|
||||
let opaque_ty = goal.predicate.alias;
|
||||
let expected = goal.predicate.term.ty().expect("no such thing as an opaque const");
|
||||
|
||||
match (goal.param_env.reveal(), self.solver_mode()) {
|
|
@ -11,10 +11,10 @@ use super::EvalCtxt;
|
|||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
pub(super) fn normalize_weak_type(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
|
||||
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let weak_ty = goal.predicate.projection_ty;
|
||||
let weak_ty = goal.predicate.alias;
|
||||
let expected = goal.predicate.term.ty().expect("no such thing as a const alias");
|
||||
|
||||
let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args);
|
23
compiler/rustc_trait_selection/src/solve/project_goals.rs
Normal file
23
compiler/rustc_trait_selection/src/solve/project_goals.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use super::EvalCtxt;
|
||||
use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
|
||||
use rustc_middle::ty::{self, ProjectionPredicate};
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
pub(super) fn compute_projection_goal(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
match goal.predicate.term.unpack() {
|
||||
ty::TermKind::Ty(term) => {
|
||||
let alias = goal.predicate.projection_ty.to_ty(self.tcx());
|
||||
self.eq(goal.param_env, alias, term)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
// FIXME(associated_const_equality): actually do something here.
|
||||
ty::TermKind::Const(_) => {
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -820,6 +820,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
// the `ParamEnv`.
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
||||
| ty::PredicateKind::NormalizesTo(..)
|
||||
| ty::PredicateKind::AliasRelate(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
|
|
|
@ -854,6 +854,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
|
||||
ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"),
|
||||
|
||||
ty::PredicateKind::NormalizesTo(..) => span_bug!(
|
||||
span,
|
||||
"NormalizesTo predicate should never be the predicate cause of a SelectionError"
|
||||
),
|
||||
|
||||
ty::PredicateKind::AliasRelate(..) => span_bug!(
|
||||
span,
|
||||
"AliasRelate predicate should never be the predicate cause of a SelectionError"
|
||||
|
|
|
@ -360,8 +360,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
|
||||
}
|
||||
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
|
||||
ty::PredicateKind::NormalizesTo(..) => {
|
||||
bug!("NormalizesTo is only used by the new solver")
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(..) => {
|
||||
bug!("AliasRelate is only used for new solver")
|
||||
bug!("AliasRelate is only used by the new solver")
|
||||
}
|
||||
},
|
||||
Some(pred) => match pred {
|
||||
|
@ -412,8 +415,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
|
||||
ty::PredicateKind::NormalizesTo(..) => {
|
||||
bug!("NormalizesTo is only used by the new solver")
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(..) => {
|
||||
bug!("AliasRelate is only used for new solver")
|
||||
bug!("AliasRelate is only used by the new solver")
|
||||
}
|
||||
|
||||
// General case overflow check. Allow `process_trait_obligation`
|
||||
|
|
|
@ -123,9 +123,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
|||
Some(pred) => pred,
|
||||
};
|
||||
match pred {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
||||
// FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
|
||||
// if we ever support that
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
|
@ -134,8 +134,8 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
|||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
| ty::PredicateKind::Ambiguous
|
||||
| ty::PredicateKind::AliasRelate(..)
|
||||
=> {}
|
||||
| ty::PredicateKind::NormalizesTo(..)
|
||||
| ty::PredicateKind::AliasRelate(..) => {}
|
||||
|
||||
// We need to search through *all* WellFormed predicates
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
|
||||
|
@ -143,10 +143,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
|||
}
|
||||
|
||||
// We need to register region relationships
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
|
||||
r_a,
|
||||
r_b,
|
||||
))) => outlives_bounds.push(ty::OutlivesPredicate(r_a.into(), r_b)),
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
|
||||
ty::OutlivesPredicate(r_a, r_b),
|
||||
)) => outlives_bounds.push(ty::OutlivesPredicate(r_a.into(), r_b)),
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
|
||||
ty_a,
|
||||
|
|
|
@ -990,8 +990,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::NormalizesTo(..) => {
|
||||
bug!("NormalizesTo is only used by the new solver")
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(..) => {
|
||||
bug!("AliasRelate is only used for new solver")
|
||||
bug!("AliasRelate is only used by the new solver")
|
||||
}
|
||||
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
||||
|
|
|
@ -25,8 +25,7 @@ impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
|
|||
// FIXME(-Ztrait-solver=next): correctly handle
|
||||
// overflow here.
|
||||
for _ in 0..256 {
|
||||
let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, projection_ty) = *ty.kind()
|
||||
else {
|
||||
let ty::Alias(ty::Projection | ty::Inherent | ty::Weak, alias) = *ty.kind() else {
|
||||
break;
|
||||
};
|
||||
|
||||
|
@ -38,10 +37,7 @@ impl<'tcx> StructurallyNormalizeExt<'tcx> for At<'_, 'tcx> {
|
|||
self.infcx.tcx,
|
||||
self.cause.clone(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::ProjectionPredicate {
|
||||
projection_ty,
|
||||
term: new_infer_ty.into(),
|
||||
}),
|
||||
ty::NormalizesTo { alias, term: new_infer_ty.into() },
|
||||
);
|
||||
if self.infcx.predicate_may_hold(&obligation) {
|
||||
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue