Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 36 additions & 18 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,22 +364,7 @@ where
goal: Goal<I, G>,
assemble_from: AssembleCandidatesFrom,
) -> Vec<Candidate<I>> {
let Ok(normalized_self_ty) =
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
else {
return vec![];
};

if normalized_self_ty.is_ty_var() {
debug!("self type has been normalized to infer");
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
}

let goal: Goal<I, G> =
goal.with(self.cx(), goal.predicate.with_self_ty(self.cx(), normalized_self_ty));
// Vars that show up in the rest of the goal substs may have been constrained by
// normalizing the self type as well, since type variables are not uniquified.
let goal = self.resolve_vars_if_possible(goal);
assert!(!goal.predicate.self_ty().is_ty_var());

let mut candidates = vec![];

Expand Down Expand Up @@ -885,6 +870,30 @@ where
}
}

pub(super) fn normalize_goal_self_ty<G: GoalKind<D>>(
&mut self,
goal: Goal<I, G>,
) -> Result<Option<Goal<I, G>>, NoSolution> {
let cx = self.cx();

let Ok(normalized_self_ty) =
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
else {
return Err(NoSolution);
};

if normalized_self_ty.is_ty_var() {
debug!("self type has been normalized to infer");
return Ok(None);
}

let goal: Goal<I, G> = goal.with(cx, goal.predicate.with_self_ty(cx, normalized_self_ty));
// Vars that show up in the rest of the goal substs may have been constrained by
// normalizing the self type as well, since type variables are not uniquified.
let goal = self.resolve_vars_if_possible(goal);
Ok(Some(goal))
}

/// Assemble and merge candidates for goals which are related to an underlying trait
/// goal. Right now, this is normalizes-to and host effect goals.
///
Expand Down Expand Up @@ -918,11 +927,20 @@ where
#[instrument(level = "debug", skip(self, inject_normalize_to_rigid_candidate), ret)]
pub(super) fn assemble_and_merge_candidates<G: GoalKind<D>>(
&mut self,
proven_via: Option<TraitGoalProvenVia>,
goal: Goal<I, G>,
inject_normalize_to_rigid_candidate: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
) -> QueryResult<I> {
let Some(proven_via) = proven_via else {
let Some(goal) = self.normalize_goal_self_ty(goal)? else {
return self.forced_ambiguity(MaybeCause::Ambiguity).map(|c| c.result);
};

let cx = self.cx();
let trait_ref = goal.predicate.trait_ref(cx);
let (_, Some(proven_via)) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
let trait_goal: Goal<I, ty::TraitPredicate<I>> = goal.with(cx, trait_ref);
ecx.compute_trait_goal_for_normalized_self_ty(trait_goal)
})?
else {
// We don't care about overflow. If proving the trait goal overflowed, then
// it's enough to report an overflow error for that, we don't also have to
// overflow during normalization.
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::solve::inspect::ProbeKind;
use rustc_type_ir::{self as ty, Interner, elaborate};
use tracing::instrument;

Expand Down Expand Up @@ -394,11 +393,6 @@ where
&mut self,
goal: Goal<I, ty::HostEffectPredicate<I>>,
) -> QueryResult<I> {
let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
let trait_goal: Goal<I, ty::TraitPredicate<I>> =
goal.with(ecx.cx(), goal.predicate.trait_ref);
ecx.compute_trait_goal(trait_goal)
})?;
self.assemble_and_merge_candidates(proven_via, goal, |_ecx| Err(NoSolution))
self.assemble_and_merge_candidates(goal, |_ecx| Err(NoSolution))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ where
if let Some(kind) = kind.no_bound_vars() {
match kind {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
self.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r)
self.compute_trait_goal(Goal { param_env, predicate })
}
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
self.compute_host_effect_goal(Goal { param_env, predicate })
Expand Down
13 changes: 3 additions & 10 deletions compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,16 @@ where
debug_assert!(self.term_is_fully_unconstrained(goal));
let cx = self.cx();
match goal.predicate.alias.kind(cx) {
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
let trait_ref = goal.predicate.alias.trait_ref(cx);
let (_, proven_via) =
self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
let trait_goal: Goal<I, ty::TraitPredicate<I>> = goal.with(cx, trait_ref);
ecx.compute_trait_goal(trait_goal)
})?;
self.assemble_and_merge_candidates(proven_via, goal, |ecx| {
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => self
.assemble_and_merge_candidates(goal, |ecx| {
ecx.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
this.structurally_instantiate_normalizes_to_term(
goal,
goal.predicate.alias,
);
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
})
}
}),
ty::AliasTermKind::InherentTy | ty::AliasTermKind::InherentConst => {
self.normalize_inherent_associated_term(goal)
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,17 @@ where
pub(super) fn compute_trait_goal(
&mut self,
goal: Goal<I, TraitPredicate<I>>,
) -> QueryResult<I> {
let Some(goal) = self.normalize_goal_self_ty(goal)? else {
return self.forced_ambiguity(MaybeCause::Ambiguity).map(|c| c.result);
};
self.compute_trait_goal_for_normalized_self_ty(goal).map(|(r, _via)| r)
}

#[instrument(level = "trace", skip(self))]
pub(super) fn compute_trait_goal_for_normalized_self_ty(
&mut self,
goal: Goal<I, TraitPredicate<I>>,
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All);
self.merge_trait_candidates(candidates)
Expand Down
Loading