Skip to content

Use let chains in the new solver #143066

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 4 additions & 4 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,10 @@ where

let mut candidates = vec![];

if let TypingMode::Coherence = self.typing_mode() {
if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) {
return vec![candidate];
}
if let TypingMode::Coherence = self.typing_mode()
&& let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal)
{
return vec![candidate];
}

self.assemble_alias_bound_candidates(goal, &mut candidates);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -997,12 +997,12 @@ where
}

fn try_fold_ty(&mut self, ty: I::Ty) -> Result<I::Ty, Ambiguous> {
if let ty::Alias(ty::Projection, alias_ty) = ty.kind() {
if let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())? {
return Ok(term.expect_ty());
}
if let ty::Alias(ty::Projection, alias_ty) = ty.kind()
&& let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())?
{
Ok(term.expect_ty())
} else {
ty.try_super_fold_with(self)
}
Copy link
Contributor

@lcnr lcnr Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vibe, no longer early return, just use else?


ty.try_super_fold_with(self)
}
}
24 changes: 11 additions & 13 deletions compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,18 @@ where
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
if let Some(host_clause) = assumption.as_host_effect_clause() {
if host_clause.def_id() == goal.predicate.def_id()
&& host_clause.constness().satisfies(goal.predicate.constness)
{
if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
host_clause.skip_binder().trait_ref.args,
) {
return Ok(());
}
}
if let Some(host_clause) = assumption.as_host_effect_clause()
&& host_clause.def_id() == goal.predicate.def_id()
&& host_clause.constness().satisfies(goal.predicate.constness)
&& DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
host_clause.skip_binder().trait_ref.args,
)
{
Ok(())
} else {
Err(NoSolution)
}

Err(NoSolution)
}

fn match_assumption(
Expand Down
59 changes: 26 additions & 33 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,22 +429,21 @@ where
// If we have run this goal before, and it was stalled, check that any of the goal's
// args have changed. Otherwise, we don't need to re-run the goal because it'll remain
// stalled, since it'll canonicalize the same way and evaluation is pure.
if let Some(stalled_on) = stalled_on {
if !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
&& !self
.delegate
.opaque_types_storage_num_entries()
.needs_reevaluation(stalled_on.num_opaques)
{
return Ok((
NestedNormalizationGoals::empty(),
GoalEvaluation {
certainty: Certainty::Maybe(stalled_on.stalled_cause),
has_changed: HasChanged::No,
stalled_on: Some(stalled_on),
},
));
}
if let Some(stalled_on) = stalled_on
&& !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
&& !self
.delegate
.opaque_types_storage_num_entries()
.needs_reevaluation(stalled_on.num_opaques)
{
return Ok((
NestedNormalizationGoals::empty(),
GoalEvaluation {
certainty: Certainty::Maybe(stalled_on.stalled_cause),
has_changed: HasChanged::No,
stalled_on: Some(stalled_on),
},
));
}

let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
Expand Down Expand Up @@ -833,14 +832,11 @@ where

match t.kind() {
ty::Infer(ty::TyVar(vid)) => {
if let ty::TermKind::Ty(term) = self.term.kind() {
if let ty::Infer(ty::TyVar(term_vid)) = term.kind() {
if self.delegate.root_ty_var(vid)
== self.delegate.root_ty_var(term_vid)
{
return ControlFlow::Break(());
}
}
if let ty::TermKind::Ty(term) = self.term.kind()
&& let ty::Infer(ty::TyVar(term_vid)) = term.kind()
&& self.delegate.root_ty_var(vid) == self.delegate.root_ty_var(term_vid)
{
return ControlFlow::Break(());
}

self.check_nameable(self.delegate.universe_of_ty(vid).unwrap())?;
Expand All @@ -860,15 +856,12 @@ where
fn visit_const(&mut self, c: I::Const) -> Self::Result {
match c.kind() {
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
if let ty::TermKind::Const(term) = self.term.kind() {
if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
{
if self.delegate.root_const_var(vid)
== self.delegate.root_const_var(term_vid)
{
return ControlFlow::Break(());
}
}
if let ty::TermKind::Const(term) = self.term.kind()
&& let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
&& self.delegate.root_const_var(vid)
== self.delegate.root_const_var(term_vid)
{
return ControlFlow::Break(());
}

self.check_nameable(self.delegate.universe_of_ct(vid).unwrap())
Expand Down
21 changes: 10 additions & 11 deletions compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,17 @@ where
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
if let Some(projection_pred) = assumption.as_projection_clause() {
if projection_pred.item_def_id() == goal.predicate.def_id() {
if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.alias.args,
projection_pred.skip_binder().projection_term.args,
) {
return Ok(());
}
}
if let Some(projection_pred) = assumption.as_projection_clause()
&& projection_pred.item_def_id() == goal.predicate.def_id()
&& DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.alias.args,
projection_pred.skip_binder().projection_term.args,
)
{
Ok(())
} else {
Err(NoSolution)
}

Err(NoSolution)
}

fn match_assumption(
Expand Down
47 changes: 23 additions & 24 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,33 +127,32 @@ where
goal: Goal<I, Self>,
assumption: I::Clause,
) -> Result<(), NoSolution> {
if let Some(trait_clause) = assumption.as_trait_clause() {
if trait_clause.polarity() != goal.predicate.polarity {
return Err(NoSolution);
}

if trait_clause.def_id() == goal.predicate.def_id() {
if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
trait_clause.skip_binder().trait_ref.args,
) {
return Ok(());
}
}

fn trait_def_id_matches<I: Interner>(
cx: I,
clause_def_id: I::DefId,
goal_def_id: I::DefId,
) -> bool {
clause_def_id == goal_def_id
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
// check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
// are syntactic sugar for a lack of bounds so don't need this.
if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized)
&& ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized)
{
let meta_sized_clause =
trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
return Self::fast_reject_assumption(ecx, goal, meta_sized_clause);
}
// check for a `MetaSized` supertrait being matched against a `Sized` assumption.
//
// `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this.
|| (cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
&& cx.is_lang_item(goal_def_id, TraitSolverLangItem::MetaSized))
}

Err(NoSolution)
if let Some(trait_clause) = assumption.as_trait_clause()
&& trait_clause.polarity() == goal.predicate.polarity
&& trait_def_id_matches(ecx.cx(), trait_clause.def_id(), goal.predicate.def_id())
&& DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
trait_clause.skip_binder().trait_ref.args,
)
{
return Ok(());
} else {
Err(NoSolution)
}
}

fn match_assumption(
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_type_ir/src/elaborate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,10 @@ pub fn supertrait_def_ids<I: Interner>(
let trait_def_id = stack.pop()?;

for (predicate, _) in cx.explicit_super_predicates_of(trait_def_id).iter_identity() {
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() {
if set.insert(data.def_id()) {
stack.push(data.def_id());
}
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder()
&& set.insert(data.def_id())
{
stack.push(data.def_id());
}
}

Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_type_ir/src/relate/solver_relating.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,12 @@ where
}

// If they have no bound vars, relate normally.
if let Some(a_inner) = a.no_bound_vars() {
if let Some(b_inner) = b.no_bound_vars() {
self.relate(a_inner, b_inner)?;
return Ok(a);
}
};
if let Some(a_inner) = a.no_bound_vars()
&& let Some(b_inner) = b.no_bound_vars()
{
self.relate(a_inner, b_inner)?;
return Ok(a);
}

match self.ambient_variance {
// Checks whether `for<..> sub <: for<..> sup` holds.
Expand Down
36 changes: 17 additions & 19 deletions compiler/rustc_type_ir/src/search_graph/global_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,29 @@ impl<X: Cx> GlobalCache<X> {
mut candidate_is_applicable: impl FnMut(&NestedGoals<X>) -> bool,
) -> Option<CacheData<'a, X>> {
let entry = self.map.get(&input)?;
if let Some(Success { required_depth, ref nested_goals, ref result }) = entry.success {
if available_depth.cache_entry_is_applicable(required_depth)
&& candidate_is_applicable(nested_goals)
{
return Some(CacheData {
result: cx.get_tracked(&result),
required_depth,
encountered_overflow: false,
nested_goals,
});
}
if let Some(Success { required_depth, ref nested_goals, ref result }) = entry.success
&& available_depth.cache_entry_is_applicable(required_depth)
&& candidate_is_applicable(nested_goals)
{
return Some(CacheData {
result: cx.get_tracked(&result),
required_depth,
encountered_overflow: false,
nested_goals,
});
}

let additional_depth = available_depth.0;
if let Some(WithOverflow { nested_goals, result }) =
entry.with_overflow.get(&additional_depth)
&& candidate_is_applicable(nested_goals)
{
if candidate_is_applicable(nested_goals) {
return Some(CacheData {
result: cx.get_tracked(result),
required_depth: additional_depth,
encountered_overflow: true,
nested_goals,
});
}
return Some(CacheData {
result: cx.get_tracked(result),
required_depth: additional_depth,
encountered_overflow: true,
nested_goals,
});
}

None
Expand Down
Loading