Rollup merge of #143066 - compiler-errors:let-chain-solver, r=lcnr

Use let chains in the new solver

Self-explanatory

Let chains are stable as of today

r? lcnr
This commit is contained in:
dianqk
2025-06-30 19:23:16 +08:00
committed by GitHub
9 changed files with 107 additions and 120 deletions

View File

@@ -383,10 +383,10 @@ where
let mut candidates = vec![]; let mut candidates = vec![];
if let TypingMode::Coherence = self.typing_mode() { if let TypingMode::Coherence = self.typing_mode()
if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) { && let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal)
return vec![candidate]; {
} return vec![candidate];
} }
self.assemble_alias_bound_candidates(goal, &mut candidates); self.assemble_alias_bound_candidates(goal, &mut candidates);

View File

@@ -997,12 +997,12 @@ where
} }
fn try_fold_ty(&mut self, ty: I::Ty) -> Result<I::Ty, Ambiguous> { 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 ty::Alias(ty::Projection, alias_ty) = ty.kind()
if let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())? { && let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())?
return Ok(term.expect_ty()); {
} Ok(term.expect_ty())
} else {
ty.try_super_fold_with(self)
} }
ty.try_super_fold_with(self)
} }
} }

View File

@@ -42,20 +42,18 @@ where
goal: Goal<I, Self>, goal: Goal<I, Self>,
assumption: I::Clause, assumption: I::Clause,
) -> Result<(), NoSolution> { ) -> Result<(), NoSolution> {
if let Some(host_clause) = assumption.as_host_effect_clause() { if let Some(host_clause) = assumption.as_host_effect_clause()
if host_clause.def_id() == goal.predicate.def_id() && host_clause.def_id() == goal.predicate.def_id()
&& host_clause.constness().satisfies(goal.predicate.constness) && host_clause.constness().satisfies(goal.predicate.constness)
{ && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args,
goal.predicate.trait_ref.args, host_clause.skip_binder().trait_ref.args,
host_clause.skip_binder().trait_ref.args, )
) { {
return Ok(()); Ok(())
} } else {
} Err(NoSolution)
} }
Err(NoSolution)
} }
fn match_assumption( fn match_assumption(

View File

@@ -429,22 +429,21 @@ where
// If we have run this goal before, and it was stalled, check that any of the goal's // 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 // 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. // stalled, since it'll canonicalize the same way and evaluation is pure.
if let Some(stalled_on) = stalled_on { if let Some(stalled_on) = stalled_on
if !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value)) && !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
&& !self && !self
.delegate .delegate
.opaque_types_storage_num_entries() .opaque_types_storage_num_entries()
.needs_reevaluation(stalled_on.num_opaques) .needs_reevaluation(stalled_on.num_opaques)
{ {
return Ok(( return Ok((
NestedNormalizationGoals::empty(), NestedNormalizationGoals::empty(),
GoalEvaluation { GoalEvaluation {
certainty: Certainty::Maybe(stalled_on.stalled_cause), certainty: Certainty::Maybe(stalled_on.stalled_cause),
has_changed: HasChanged::No, has_changed: HasChanged::No,
stalled_on: Some(stalled_on), stalled_on: Some(stalled_on),
}, },
)); ));
}
} }
let (orig_values, canonical_goal) = self.canonicalize_goal(goal); let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
@@ -833,14 +832,11 @@ where
match t.kind() { match t.kind() {
ty::Infer(ty::TyVar(vid)) => { ty::Infer(ty::TyVar(vid)) => {
if let ty::TermKind::Ty(term) = self.term.kind() { if let ty::TermKind::Ty(term) = self.term.kind()
if let ty::Infer(ty::TyVar(term_vid)) = term.kind() { && let ty::Infer(ty::TyVar(term_vid)) = term.kind()
if self.delegate.root_ty_var(vid) && self.delegate.root_ty_var(vid) == self.delegate.root_ty_var(term_vid)
== self.delegate.root_ty_var(term_vid) {
{ return ControlFlow::Break(());
return ControlFlow::Break(());
}
}
} }
self.check_nameable(self.delegate.universe_of_ty(vid).unwrap())?; self.check_nameable(self.delegate.universe_of_ty(vid).unwrap())?;
@@ -860,15 +856,12 @@ where
fn visit_const(&mut self, c: I::Const) -> Self::Result { fn visit_const(&mut self, c: I::Const) -> Self::Result {
match c.kind() { match c.kind() {
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
if let ty::TermKind::Const(term) = self.term.kind() { if let ty::TermKind::Const(term) = self.term.kind()
if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind() && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
{ && self.delegate.root_const_var(vid)
if self.delegate.root_const_var(vid) == self.delegate.root_const_var(term_vid)
== self.delegate.root_const_var(term_vid) {
{ return ControlFlow::Break(());
return ControlFlow::Break(());
}
}
} }
self.check_nameable(self.delegate.universe_of_ct(vid).unwrap()) self.check_nameable(self.delegate.universe_of_ct(vid).unwrap())

View File

@@ -112,18 +112,17 @@ where
goal: Goal<I, Self>, goal: Goal<I, Self>,
assumption: I::Clause, assumption: I::Clause,
) -> Result<(), NoSolution> { ) -> Result<(), NoSolution> {
if let Some(projection_pred) = assumption.as_projection_clause() { if let Some(projection_pred) = assumption.as_projection_clause()
if projection_pred.item_def_id() == goal.predicate.def_id() { && projection_pred.item_def_id() == goal.predicate.def_id()
if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.alias.args, goal.predicate.alias.args,
projection_pred.skip_binder().projection_term.args, projection_pred.skip_binder().projection_term.args,
) { )
return Ok(()); {
} Ok(())
} } else {
Err(NoSolution)
} }
Err(NoSolution)
} }
fn match_assumption( fn match_assumption(

View File

@@ -127,33 +127,32 @@ where
goal: Goal<I, Self>, goal: Goal<I, Self>,
assumption: I::Clause, assumption: I::Clause,
) -> Result<(), NoSolution> { ) -> Result<(), NoSolution> {
if let Some(trait_clause) = assumption.as_trait_clause() { fn trait_def_id_matches<I: Interner>(
if trait_clause.polarity() != goal.predicate.polarity { cx: I,
return Err(NoSolution); clause_def_id: I::DefId,
} goal_def_id: I::DefId,
) -> bool {
if trait_clause.def_id() == goal.predicate.def_id() { clause_def_id == goal_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(());
}
}
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
// check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds // check for a `MetaSized` supertrait being matched against a `Sized` assumption.
// 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) // `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this.
&& ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized) || (cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
{ && cx.is_lang_item(goal_def_id, TraitSolverLangItem::MetaSized))
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);
}
} }
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( fn match_assumption(

View File

@@ -320,10 +320,10 @@ pub fn supertrait_def_ids<I: Interner>(
let trait_def_id = stack.pop()?; let trait_def_id = stack.pop()?;
for (predicate, _) in cx.explicit_super_predicates_of(trait_def_id).iter_identity() { for (predicate, _) in cx.explicit_super_predicates_of(trait_def_id).iter_identity() {
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() { if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder()
if set.insert(data.def_id()) { && set.insert(data.def_id())
stack.push(data.def_id()); {
} stack.push(data.def_id());
} }
} }

View File

@@ -284,12 +284,12 @@ where
} }
// If they have no bound vars, relate normally. // If they have no bound vars, relate normally.
if let Some(a_inner) = a.no_bound_vars() { if let Some(a_inner) = a.no_bound_vars()
if let Some(b_inner) = b.no_bound_vars() { && let Some(b_inner) = b.no_bound_vars()
self.relate(a_inner, b_inner)?; {
return Ok(a); self.relate(a_inner, b_inner)?;
} return Ok(a);
}; }
match self.ambient_variance { match self.ambient_variance {
// Checks whether `for<..> sub <: for<..> sup` holds. // Checks whether `for<..> sub <: for<..> sup` holds.

View File

@@ -80,31 +80,29 @@ impl<X: Cx> GlobalCache<X> {
mut candidate_is_applicable: impl FnMut(&NestedGoals<X>) -> bool, mut candidate_is_applicable: impl FnMut(&NestedGoals<X>) -> bool,
) -> Option<CacheData<'a, X>> { ) -> Option<CacheData<'a, X>> {
let entry = self.map.get(&input)?; let entry = self.map.get(&input)?;
if let Some(Success { required_depth, ref nested_goals, ref result }) = entry.success { if let Some(Success { required_depth, ref nested_goals, ref result }) = entry.success
if available_depth.cache_entry_is_applicable(required_depth) && available_depth.cache_entry_is_applicable(required_depth)
&& candidate_is_applicable(nested_goals) && candidate_is_applicable(nested_goals)
{ {
return Some(CacheData { return Some(CacheData {
result: cx.get_tracked(&result), result: cx.get_tracked(&result),
required_depth, required_depth,
encountered_overflow: false, encountered_overflow: false,
nested_goals, nested_goals,
}); });
}
} }
let additional_depth = available_depth.0; let additional_depth = available_depth.0;
if let Some(WithOverflow { nested_goals, result }) = if let Some(WithOverflow { nested_goals, result }) =
entry.with_overflow.get(&additional_depth) entry.with_overflow.get(&additional_depth)
&& candidate_is_applicable(nested_goals)
{ {
if candidate_is_applicable(nested_goals) { return Some(CacheData {
return Some(CacheData { result: cx.get_tracked(result),
result: cx.get_tracked(result), required_depth: additional_depth,
required_depth: additional_depth, encountered_overflow: true,
encountered_overflow: true, nested_goals,
nested_goals, });
});
}
} }
None None