@@ -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,30 @@ 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
+ // See trait-system-refactor-initiative#226 for some ideas here.
410
+ if TypingMode :: Coherence == self . typing_mode ( )
411
+ || !candidates. iter ( ) . any ( |c| {
412
+ matches ! (
413
+ c. source,
414
+ CandidateSource :: ParamEnv ( ParamEnvSource :: NonGlobal )
415
+ | CandidateSource :: AliasBound
416
+ ) && has_no_inference_or_external_constraints ( c. result )
417
+ } )
418
+ {
419
+ self . assemble_impl_candidates ( goal, & mut candidates) ;
420
+ self . assemble_object_bound_candidates ( goal, & mut candidates) ;
421
+ }
401
422
}
402
423
AssembleCandidatesFrom :: EnvAndBounds => { }
403
424
}
0 commit comments