Skip to content

Commit 644250d

Browse files
committed
refactor compute_goal_fast_path: turn into a single match
1 parent 4ddd453 commit 644250d

1 file changed

Lines changed: 57 additions & 32 deletions

File tree

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_infer::traits::solve::{FetchEligibleAssocItemResponse, Goal};
1313
use rustc_middle::traits::query::NoSolution;
1414
use rustc_middle::traits::solve::Certainty;
1515
use rustc_middle::ty::{
16-
self, MayBeErased, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
16+
self, MayBeErased, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt, TypingMode,
1717
};
1818
use rustc_span::{DUMMY_SP, Span};
1919

@@ -73,51 +73,60 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
7373
goal: Goal<'tcx, ty::Predicate<'tcx>>,
7474
span: Span,
7575
) -> Option<Certainty> {
76-
if let Some(trait_pred) = goal.predicate.as_trait_clause() {
77-
if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
76+
let pred = goal.predicate.kind();
77+
match pred.skip_binder() {
78+
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
79+
let trait_pred = pred.rebind(trait_pred);
80+
81+
if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
7882
// We don't do this fast path when opaques are defined since we may
7983
// eventually use opaques to incompletely guide inference via ty var
8084
// self types.
8185
// FIXME: Properly consider opaques here.
8286
&& self.known_no_opaque_types_in_storage()
83-
{
84-
return Some(Certainty::AMBIGUOUS);
85-
}
86-
87-
if trait_pred.polarity() == ty::PredicatePolarity::Positive {
88-
match self.0.tcx.as_lang_item(trait_pred.def_id()) {
89-
Some(LangItem::Sized) | Some(LangItem::MetaSized) => {
90-
let predicate = self.resolve_vars_if_possible(goal.predicate);
91-
if sizedness_fast_path(self.tcx, predicate, goal.param_env) {
92-
return Some(Certainty::Yes);
87+
{
88+
Some(Certainty::AMBIGUOUS)
89+
} else if trait_pred.polarity() == ty::PredicatePolarity::Positive {
90+
match self.0.tcx.as_lang_item(trait_pred.def_id()) {
91+
Some(LangItem::Sized) | Some(LangItem::MetaSized) => {
92+
let predicate = self.resolve_vars_if_possible(goal.predicate);
93+
if sizedness_fast_path(self.tcx, predicate, goal.param_env) {
94+
return Some(Certainty::Yes);
95+
} else {
96+
None
97+
}
9398
}
94-
}
95-
Some(LangItem::Copy | LangItem::Clone) => {
96-
let self_ty =
97-
self.resolve_vars_if_possible(trait_pred.self_ty().skip_binder());
98-
// Unlike `Sized` traits, which always prefer the built-in impl,
99-
// `Copy`/`Clone` may be shadowed by a param-env candidate which
100-
// could force a lifetime error or guide inference. While that's
101-
// not generally desirable, it is observable, so for now let's
102-
// ignore this fast path for types that have regions or infer.
103-
if !self_ty
104-
.has_type_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_INFER)
105-
&& self_ty.is_trivially_pure_clone_copy()
106-
{
107-
return Some(Certainty::Yes);
99+
Some(LangItem::Copy | LangItem::Clone) => {
100+
let self_ty =
101+
self.resolve_vars_if_possible(trait_pred.self_ty().skip_binder());
102+
// Unlike `Sized` traits, which always prefer the built-in impl,
103+
// `Copy`/`Clone` may be shadowed by a param-env candidate which
104+
// could force a lifetime error or guide inference. While that's
105+
// not generally desirable, it is observable, so for now let's
106+
// ignore this fast path for types that have regions or infer.
107+
if !self_ty
108+
.has_type_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_INFER)
109+
&& self_ty.is_trivially_pure_clone_copy()
110+
{
111+
return Some(Certainty::Yes);
112+
} else {
113+
None
114+
}
108115
}
116+
_ => None,
109117
}
110-
_ => {}
118+
} else {
119+
None
111120
}
112121
}
113-
}
114-
115-
let pred = goal.predicate.kind();
116-
match pred.no_bound_vars()? {
117122
ty::PredicateKind::DynCompatible(def_id) if self.0.tcx.is_dyn_compatible(def_id) => {
118123
Some(Certainty::Yes)
119124
}
120125
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(outlives)) => {
126+
if outlives.has_escaping_bound_vars() {
127+
return None;
128+
}
129+
121130
self.0.sub_regions(
122131
SubregionOrigin::RelateRegionParamBound(span, None),
123132
outlives.1,
@@ -127,6 +136,10 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
127136
Some(Certainty::Yes)
128137
}
129138
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
139+
if outlives.has_escaping_bound_vars() {
140+
return None;
141+
}
142+
130143
self.0.register_type_outlives_constraint(
131144
outlives.0,
132145
outlives.1,
@@ -137,6 +150,10 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
137150
}
138151
ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, .. })
139152
| ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
153+
if a.has_escaping_bound_vars() || b.has_escaping_bound_vars() {
154+
return None;
155+
}
156+
140157
match (self.shallow_resolve(a).kind(), self.shallow_resolve(b).kind()) {
141158
(&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => {
142159
self.sub_unify_ty_vids_raw(a_vid, b_vid);
@@ -146,13 +163,21 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
146163
}
147164
}
148165
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) => {
166+
if ct.has_escaping_bound_vars() {
167+
return None;
168+
}
169+
149170
if self.shallow_resolve_const(ct).is_ct_infer() {
150171
Some(Certainty::AMBIGUOUS)
151172
} else {
152173
None
153174
}
154175
}
155176
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
177+
if arg.has_escaping_bound_vars() {
178+
return None;
179+
}
180+
156181
let arg = self.shallow_resolve_term(arg);
157182
if arg.is_trivially_wf(self.tcx) {
158183
Some(Certainty::Yes)

0 commit comments

Comments
 (0)