1
1
//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
2
2
3
+ use std:: cell:: Cell ;
4
+
3
5
use rustc_type_ir:: data_structures:: IndexSet ;
4
6
use rustc_type_ir:: fast_reject:: DeepRejectCtxt ;
5
7
use rustc_type_ir:: inherent:: * ;
@@ -14,7 +16,7 @@ use tracing::{debug, instrument, trace};
14
16
use crate :: delegate:: SolverDelegate ;
15
17
use crate :: solve:: assembly:: structural_traits:: { self , AsyncCallableRelevantTypes } ;
16
18
use crate :: solve:: assembly:: { self , AllowInferenceConstraints , AssembleCandidatesFrom , Candidate } ;
17
- use crate :: solve:: inspect:: ProbeKind ;
19
+ use crate :: solve:: inspect:: { self , ProbeKind } ;
18
20
use crate :: solve:: {
19
21
BuiltinImplSource , CandidateSource , Certainty , EvalCtxt , Goal , GoalSource , MaybeCause ,
20
22
NoSolution , ParamEnvSource , QueryResult , has_only_region_constraints,
41
43
self . def_id ( )
42
44
}
43
45
46
+ fn assemble_param_env_candidates_fast_path (
47
+ ecx : & mut EvalCtxt < ' _ , D > ,
48
+ goal : Goal < I , Self > ,
49
+ ) -> Option < Candidate < I > > {
50
+ // This is kind of a mess. We need to detect whether there's an applicable
51
+ // `ParamEnv` candidate without fully normalizing other candidates to avoid the
52
+ // hang in trait-system-refactor-initiative#210. This currently uses structural
53
+ // identity, which means it does not apply if there are normalizeable aliases
54
+ // in the environment or if the goal is higher ranked.
55
+ //
56
+ // We generally need such a fast path if multiple potentially applicable where-bounds
57
+ // contain aliases whose normalization tries to apply all these where-bounds yet again.
58
+ // This can easily result in exponential blowup.
59
+ for assumption in goal. param_env . caller_bounds ( ) . iter ( ) . filter_map ( |c| c. as_trait_clause ( ) )
60
+ {
61
+ if assumption. no_bound_vars ( ) . is_some_and ( |c| c == goal. predicate ) {
62
+ let source = Cell :: new ( CandidateSource :: ParamEnv ( ParamEnvSource :: Global ) ) ;
63
+ let Ok ( candidate) = ecx
64
+ . probe ( |result : & QueryResult < I > | inspect:: ProbeKind :: TraitCandidate {
65
+ source : source. get ( ) ,
66
+ result : * result,
67
+ } )
68
+ . enter ( |ecx| {
69
+ source. set ( ecx. characterize_param_env_assumption (
70
+ goal. param_env ,
71
+ assumption. upcast ( ecx. cx ( ) ) ,
72
+ ) ?) ;
73
+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
74
+ } )
75
+ . map ( |result| Candidate { source : source. get ( ) , result } )
76
+ else {
77
+ continue ;
78
+ } ;
79
+ if candidate. source == CandidateSource :: ParamEnv ( ParamEnvSource :: NonGlobal ) {
80
+ return Some ( candidate) ;
81
+ }
82
+ }
83
+ }
84
+ None
85
+ }
86
+
44
87
fn consider_additional_alias_assumptions (
45
88
_ecx : & mut EvalCtxt < ' _ , D > ,
46
89
_goal : Goal < I , Self > ,
0 commit comments