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