|
2 | 2 |
|
3 | 3 | pub(super) mod structural_traits;
|
4 | 4 |
|
| 5 | +use std::cell::Cell; |
5 | 6 | use std::ops::ControlFlow;
|
6 | 7 |
|
7 | 8 | use derive_where::derive_where;
|
@@ -118,25 +119,23 @@ where
|
118 | 119 | Self::fast_reject_assumption(ecx, goal, assumption)?;
|
119 | 120 |
|
120 | 121 | // Dealing with `ParamEnv` candidates is a bit of a mess as we need to lazily
|
121 |
| - // check whether the candidate is global. |
122 |
| - ecx.probe(|candidate: &Result<Candidate<I>, NoSolution>| match candidate { |
123 |
| - Ok(candidate) => inspect::ProbeKind::TraitCandidate { |
124 |
| - source: candidate.source, |
125 |
| - result: Ok(candidate.result), |
126 |
| - }, |
127 |
| - Err(NoSolution) => inspect::ProbeKind::TraitCandidate { |
128 |
| - source: CandidateSource::ParamEnv(ParamEnvSource::Global), |
129 |
| - result: Err(NoSolution), |
130 |
| - }, |
| 122 | + // check whether the candidate is global while considering normalization. |
| 123 | + // |
| 124 | + // We need to write into `source` inside of `match_assumption`, but need to access it |
| 125 | + // in `probe` even if the candidate does not apply before we get there. This forces |
| 126 | + // us to use a `Cell` here. We only ever write into it inside of `match_assumption`. |
| 127 | + let source = Cell::new(CandidateSource::ParamEnv(ParamEnvSource::Global)); |
| 128 | + ecx.probe(|result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate { |
| 129 | + source: source.get(), |
| 130 | + result: *result, |
131 | 131 | })
|
132 | 132 | .enter(|ecx| {
|
133 |
| - let mut source = CandidateSource::ParamEnv(ParamEnvSource::Global); |
134 |
| - let result = Self::match_assumption(ecx, goal, assumption, |ecx| { |
135 |
| - source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?; |
| 133 | + Self::match_assumption(ecx, goal, assumption, |ecx| { |
| 134 | + source.set(ecx.characterize_param_env_assumption(goal.param_env, assumption)?); |
136 | 135 | ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
137 |
| - })?; |
138 |
| - Ok(Candidate { source, result }) |
| 136 | + }) |
139 | 137 | })
|
| 138 | + .map(|result| Candidate { source: source.get(), result }) |
140 | 139 | }
|
141 | 140 |
|
142 | 141 | /// Try equating an assumption predicate against a goal's predicate. If it
|
|
0 commit comments