|
1 | 1 | //! Code shared by trait and projection goals for candidate assembly.
|
2 | 2 |
|
| 3 | +use super::search_graph::OverflowHandler; |
3 | 4 | #[cfg(doc)]
|
4 | 5 | use super::trait_goals::structural_traits::*;
|
5 | 6 | use super::{EvalCtxt, SolverMode};
|
@@ -279,25 +280,38 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
279 | 280 | return
|
280 | 281 | };
|
281 | 282 |
|
282 |
| - self.probe(|ecx| { |
283 |
| - let normalized_ty = ecx.next_ty_infer(); |
284 |
| - let normalizes_to_goal = goal.with( |
285 |
| - tcx, |
286 |
| - ty::Binder::dummy(ty::ProjectionPredicate { |
287 |
| - projection_ty, |
288 |
| - term: normalized_ty.into(), |
289 |
| - }), |
290 |
| - ); |
291 |
| - ecx.add_goal(normalizes_to_goal); |
292 |
| - if let Ok(_) = ecx.try_evaluate_added_goals() { |
293 |
| - let normalized_ty = ecx.resolve_vars_if_possible(normalized_ty); |
294 |
| - |
295 |
| - // NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate. |
296 |
| - // This doesn't work as long as we use `CandidateSource` in winnowing. |
297 |
| - let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty)); |
298 |
| - candidates.extend(ecx.assemble_and_evaluate_candidates(goal)); |
299 |
| - } |
| 283 | + let normalized_self_candidates: Result<_, NoSolution> = self.probe(|ecx| { |
| 284 | + ecx.with_incremented_depth( |
| 285 | + |ecx| { |
| 286 | + let result = ecx.evaluate_added_goals_and_make_canonical_response( |
| 287 | + Certainty::Maybe(MaybeCause::Overflow), |
| 288 | + )?; |
| 289 | + Ok(vec![Candidate { source: CandidateSource::BuiltinImpl, result }]) |
| 290 | + }, |
| 291 | + |ecx| { |
| 292 | + let normalized_ty = ecx.next_ty_infer(); |
| 293 | + let normalizes_to_goal = goal.with( |
| 294 | + tcx, |
| 295 | + ty::Binder::dummy(ty::ProjectionPredicate { |
| 296 | + projection_ty, |
| 297 | + term: normalized_ty.into(), |
| 298 | + }), |
| 299 | + ); |
| 300 | + ecx.add_goal(normalizes_to_goal); |
| 301 | + let _ = ecx.try_evaluate_added_goals()?; |
| 302 | + let normalized_ty = ecx.resolve_vars_if_possible(normalized_ty); |
| 303 | + // NOTE: Alternatively we could call `evaluate_goal` here and only |
| 304 | + // have a `Normalized` candidate. This doesn't work as long as we |
| 305 | + // use `CandidateSource` in winnowing. |
| 306 | + let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty)); |
| 307 | + Ok(ecx.assemble_and_evaluate_candidates(goal)) |
| 308 | + }, |
| 309 | + ) |
300 | 310 | });
|
| 311 | + |
| 312 | + if let Ok(normalized_self_candidates) = normalized_self_candidates { |
| 313 | + candidates.extend(normalized_self_candidates); |
| 314 | + } |
301 | 315 | }
|
302 | 316 |
|
303 | 317 | fn assemble_impl_candidates<G: GoalKind<'tcx>>(
|
|
0 commit comments