Skip to content

Commit b503949

Browse files
Rollup merge of #156172 - ShoyuVanilla:slowbro, r=lcnr
Implement a new flag `-Zdisable-fast-paths` in trait solving Discussion: [#t-types/trait-system-refactor > ask for help @ 💬](https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/ask.20for.20help/near/583953725) r? lcnr
2 parents 73e5912 + 4432f6b commit b503949

11 files changed

Lines changed: 42 additions & 8 deletions

File tree

compiler/rustc_infer/src/infer/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
2222
self.next_trait_solver
2323
}
2424

25+
fn disable_trait_solver_fast_paths(&self) -> bool {
26+
self.disable_trait_solver_fast_paths()
27+
}
28+
2529
fn typing_mode(&self) -> ty::TypingMode<'tcx> {
2630
self.typing_mode()
2731
}

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,11 @@ impl<'tcx> InferCtxt<'tcx> {
640640
self.next_trait_solver
641641
}
642642

643+
#[inline(always)]
644+
pub fn disable_trait_solver_fast_paths(&self) -> bool {
645+
self.tcx.disable_trait_solver_fast_paths()
646+
}
647+
643648
#[inline(always)]
644649
pub fn typing_mode(&self) -> TypingMode<'tcx> {
645650
self.typing_mode

compiler/rustc_middle/src/ty/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,6 +2657,10 @@ impl<'tcx> TyCtxt<'tcx> {
26572657
self.sess.opts.unstable_opts.next_solver.coherence
26582658
}
26592659

2660+
pub fn disable_trait_solver_fast_paths(self) -> bool {
2661+
self.sess.opts.unstable_opts.disable_fast_paths
2662+
}
2663+
26602664
#[allow(rustc::bad_opt_access)]
26612665
pub fn use_typing_mode_borrowck(self) -> bool {
26622666
self.next_trait_solver_globally() || self.sess.opts.unstable_opts.typing_mode_borrowck

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ where
447447
ref sub_roots,
448448
stalled_certainty,
449449
}) = stalled_on
450+
&& !self.delegate.disable_trait_solver_fast_paths()
450451
&& !stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
451452
&& !sub_roots
452453
.iter()
@@ -666,7 +667,10 @@ where
666667
// If this loop did not result in any progress, what's our final certainty.
667668
let mut unchanged_certainty = Some(Certainty::Yes);
668669
for (source, goal, stalled_on) in mem::take(&mut self.nested_goals) {
669-
if let Some(certainty) = self.delegate.compute_goal_fast_path(goal, self.origin_span) {
670+
if !self.delegate.disable_trait_solver_fast_paths()
671+
&& let Some(certainty) =
672+
self.delegate.compute_goal_fast_path(goal, self.origin_span)
673+
{
670674
match certainty {
671675
Certainty::Yes => {}
672676
Certainty::Maybe { .. } => {

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,8 @@ options! {
22692269
themselves (default: no)"),
22702270
direct_access_external_data: Option<bool> = (None, parse_opt_bool, [TRACKED],
22712271
"Direct or use GOT indirect to reference external data symbols"),
2272+
disable_fast_paths: bool = (false, parse_bool, [TRACKED],
2273+
"disable various performance optimizations in trait solving"),
22722274
dual_proc_macros: bool = (false, parse_bool, [TRACKED],
22732275
"load proc macros for both target and host, but only link to the target (default: no)"),
22742276
dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,9 @@ where
186186

187187
let goal = obligation.as_goal();
188188
let delegate = <&SolverDelegate<'tcx>>::from(infcx);
189-
if let Some(certainty) =
190-
delegate.compute_goal_fast_path(goal, obligation.cause.span)
189+
if !delegate.disable_trait_solver_fast_paths()
190+
&& let Some(certainty) =
191+
delegate.compute_goal_fast_path(goal, obligation.cause.span)
191192
{
192193
match certainty {
193194
// This fast path doesn't depend on region identity so it doesn't

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
325325
/// compile-time benchmarks are very sensitive to even small changes.
326326
#[inline(always)]
327327
fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
328+
if self.selcx.infcx.disable_trait_solver_fast_paths() {
329+
return true;
330+
}
331+
328332
// If we were stalled on some unresolved variables, first check whether
329333
// any of them have been resolved; if not, don't bother doing more work
330334
// yet.
@@ -388,7 +392,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
388392

389393
let infcx = self.selcx.infcx;
390394

391-
if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) {
395+
if !infcx.disable_trait_solver_fast_paths()
396+
&& sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env)
397+
{
392398
return ProcessResult::Changed(thin_vec![]);
393399
}
394400

compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
110110
),
111111
NoSolution,
112112
> {
113-
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
113+
if !infcx.disable_trait_solver_fast_paths()
114+
&& let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key)
115+
{
114116
return Ok((result, None, PredicateObligations::new(), Certainty::Proven));
115117
}
116118

@@ -159,7 +161,9 @@ where
159161
"query type op",
160162
span,
161163
|ocx| {
162-
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &self) {
164+
if !infcx.disable_trait_solver_fast_paths()
165+
&& let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &self)
166+
{
163167
return Ok(result);
164168
}
165169
QueryTypeOp::perform_locally_with_next_solver(ocx, self, span)

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
604604
None => self.check_recursion_limit(&obligation, &obligation)?,
605605
}
606606

607-
if sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env) {
607+
if !self.infcx.disable_trait_solver_fast_paths()
608+
&& sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env)
609+
{
608610
return Ok(EvaluatedToOk);
609611
}
610612

compiler/rustc_traits/src/evaluate_obligation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn evaluate_obligation<'tcx>(
2424
debug!("evaluate_obligation: goal={:#?}", goal);
2525
let ParamEnvAnd { param_env, value: predicate } = goal;
2626

27-
if sizedness_fast_path(tcx, predicate, param_env) {
27+
if !tcx.disable_trait_solver_fast_paths() && sizedness_fast_path(tcx, predicate, param_env) {
2828
return Ok(EvaluationResult::EvaluatedToOk);
2929
}
3030

0 commit comments

Comments
 (0)