@@ -21,7 +21,7 @@ use crate::delegate::SolverDelegate;
2121use crate :: solve:: inspect:: ProbeKind ;
2222use crate :: solve:: {
2323 BuiltinImplSource , CandidateSource , CanonicalResponse , Certainty , EvalCtxt , Goal , GoalSource ,
24- MaybeCause , NoSolution , ParamEnvSource , QueryResult ,
24+ MaybeCause , NoSolution , ParamEnvSource , QueryResult , has_no_inference_or_external_constraints ,
2525} ;
2626
2727enum AliasBoundKind {
@@ -395,9 +395,29 @@ where
395395
396396 match assemble_from {
397397 AssembleCandidatesFrom :: All => {
398- self . assemble_impl_candidates ( goal, & mut candidates) ;
399398 self . assemble_builtin_impl_candidates ( goal, & mut candidates) ;
400- self . assemble_object_bound_candidates ( goal, & mut candidates) ;
399+ // For performance we only assemble impls if there are no candidates
400+ // which would shadow them. This is necessary to avoid hangs in rayon,
401+ // see trait-system-refactor-initiative#109 for more details.
402+ //
403+ // We always assemble builtin impls as trivial builtin impls have a higher
404+ // priority than where-clauses.
405+ //
406+ // We only do this if any such candidate applies without any constraints
407+ // as we may want to weaken inference guidance in the future and don't want
408+ // to worry about causing major performance regressions when doing so.
409+ if TypingMode :: Coherence == self . typing_mode ( )
410+ || !candidates. iter ( ) . any ( |c| {
411+ matches ! (
412+ c. source,
413+ CandidateSource :: ParamEnv ( ParamEnvSource :: NonGlobal )
414+ | CandidateSource :: AliasBound
415+ ) && has_no_inference_or_external_constraints ( c. result )
416+ } )
417+ {
418+ self . assemble_impl_candidates ( goal, & mut candidates) ;
419+ self . assemble_object_bound_candidates ( goal, & mut candidates) ;
420+ }
401421 }
402422 AssembleCandidatesFrom :: EnvAndBounds => { }
403423 }
0 commit comments