@@ -21,7 +21,7 @@ use crate::delegate::SolverDelegate;
21
21
use crate :: solve:: inspect:: ProbeKind ;
22
22
use crate :: solve:: {
23
23
BuiltinImplSource , CandidateSource , CanonicalResponse , Certainty , EvalCtxt , Goal , GoalSource ,
24
- MaybeCause , NoSolution , ParamEnvSource , QueryResult ,
24
+ MaybeCause , NoSolution , ParamEnvSource , QueryResult , has_no_inference_or_external_constraints ,
25
25
} ;
26
26
27
27
enum AliasBoundKind {
@@ -395,9 +395,29 @@ where
395
395
396
396
match assemble_from {
397
397
AssembleCandidatesFrom :: All => {
398
- self . assemble_impl_candidates ( goal, & mut candidates) ;
399
398
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
+ }
401
421
}
402
422
AssembleCandidatesFrom :: EnvAndBounds => { }
403
423
}
0 commit comments