@@ -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,28 @@ 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
+ //
402
+ // We always assemble builtin impls as trivial builtin impls have a higher
403
+ // priority than where-clauses.
404
+ //
405
+ // We only do this if any such candidate applies without any constraints
406
+ // as we may want to weaken inference guidance in the future and don't want
407
+ // to worry about causing major performance regressions when doing so.
408
+ if TypingMode :: Coherence == self . typing_mode ( )
409
+ || !candidates. iter ( ) . any ( |c| {
410
+ matches ! (
411
+ c. source,
412
+ CandidateSource :: ParamEnv ( ParamEnvSource :: NonGlobal )
413
+ | CandidateSource :: AliasBound
414
+ ) && has_no_inference_or_external_constraints ( c. result )
415
+ } )
416
+ {
417
+ self . assemble_impl_candidates ( goal, & mut candidates) ;
418
+ self . assemble_object_bound_candidates ( goal, & mut candidates) ;
419
+ }
401
420
}
402
421
AssembleCandidatesFrom :: EnvAndBounds => { }
403
422
}
0 commit comments