Skip to content

Commit 9c3fe58

Browse files
committed
small refactor to new projection code
1 parent db137ba commit 9c3fe58

File tree

1 file changed

+40
-37
lines changed

1 file changed

+40
-37
lines changed

compiler/rustc_trait_selection/src/solve/project_goals.rs

+40-37
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
122122
&& goal.param_env.visit_with(&mut visitor).is_continue()
123123
}
124124

125+
/// After normalizing the projection to `normalized_alias` with the given
126+
/// `normalization_certainty`, constrain the inference variable `term` to it
127+
/// and return a query response.
128+
fn eq_term_and_make_canonical_response(
129+
&mut self,
130+
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
131+
normalization_certainty: Certainty,
132+
normalized_alias: impl Into<ty::Term<'tcx>>,
133+
) -> QueryResult<'tcx> {
134+
// The term of our goal should be fully unconstrained, so this should never fail.
135+
//
136+
// It can however be ambiguous when the `normalized_alias` contains a projection.
137+
let nested_goals = self
138+
.infcx
139+
.eq(goal.param_env, goal.predicate.term, normalized_alias.into())
140+
.expect("failed to unify with unconstrained term");
141+
let rhs_certainty =
142+
self.evaluate_all(nested_goals).expect("failed to unify with unconstrained term");
143+
144+
self.make_canonical_response(normalization_certainty.unify_and(rhs_certainty))
145+
}
146+
125147
fn merge_project_candidates(
126148
&mut self,
127149
mut candidates: Vec<Candidate<'tcx>>,
@@ -218,7 +240,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
218240
.map(|pred| goal.with(tcx, pred));
219241

220242
nested_goals.extend(where_clause_bounds);
221-
let trait_ref_certainty = ecx.evaluate_all(nested_goals)?;
243+
let match_impl_certainty = ecx.evaluate_all(nested_goals)?;
222244

223245
// In case the associated item is hidden due to specialization, we have to
224246
// return ambiguity this would otherwise be incomplete, resulting in
@@ -230,7 +252,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
230252
goal.predicate.def_id(),
231253
impl_def_id
232254
)? else {
233-
return ecx.make_canonical_response(trait_ref_certainty.unify_and(Certainty::AMBIGUOUS));
255+
return ecx.make_canonical_response(match_impl_certainty.unify_and(Certainty::AMBIGUOUS));
234256
};
235257

236258
if !assoc_def.item.defaultness(tcx).has_value() {
@@ -277,17 +299,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
277299
ty.map_bound(|ty| ty.into())
278300
};
279301

280-
// The term of our goal should be fully unconstrained, so this should never fail.
281-
//
282-
// It can however be ambiguous when the resolved type is a projection.
283-
let nested_goals = ecx
284-
.infcx
285-
.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))
286-
.expect("failed to unify with unconstrained term");
287-
let rhs_certainty =
288-
ecx.evaluate_all(nested_goals).expect("failed to unify with unconstrained term");
289-
290-
ecx.make_canonical_response(trait_ref_certainty.unify_and(rhs_certainty))
302+
ecx.eq_term_and_make_canonical_response(goal, match_impl_certainty, term.subst(tcx, substs))
291303
})
292304
}
293305

@@ -307,18 +319,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
307319
)?;
308320
let subst_certainty = ecx.evaluate_all(nested_goals)?;
309321

310-
// The term of our goal should be fully unconstrained, so this should never fail.
311-
//
312-
// It can however be ambiguous when the resolved type is a projection.
313-
let nested_goals = ecx
314-
.infcx
315-
.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)
316-
.expect("failed to unify with unconstrained term");
317-
let rhs_certainty = ecx
318-
.evaluate_all(nested_goals)
319-
.expect("failed to unify with unconstrained term");
320-
321-
ecx.make_canonical_response(subst_certainty.unify_and(rhs_certainty))
322+
ecx.eq_term_and_make_canonical_response(
323+
goal,
324+
subst_certainty,
325+
assumption_projection_pred.term,
326+
)
322327
})
323328
} else {
324329
Err(NoSolution)
@@ -434,14 +439,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
434439
[ty::GenericArg::from(goal.predicate.self_ty())],
435440
));
436441

437-
let mut nested_goals = ecx.infcx.eq(
438-
goal.param_env,
439-
goal.predicate.term.ty().unwrap(),
442+
let is_sized_certainty = ecx.evaluate_goal(goal.with(tcx, sized_predicate))?.1;
443+
return ecx.eq_term_and_make_canonical_response(
444+
goal,
445+
is_sized_certainty,
440446
tcx.types.unit,
441-
)?;
442-
nested_goals.push(goal.with(tcx, sized_predicate));
443-
444-
return ecx.evaluate_all_and_make_canonical_response(nested_goals);
447+
);
445448
}
446449

447450
ty::Adt(def, substs) if def.is_struct() => {
@@ -453,7 +456,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
453456
tcx,
454457
ty::Binder::dummy(goal.predicate.with_self_ty(tcx, self_ty)),
455458
);
456-
return ecx.evaluate_all_and_make_canonical_response(vec![new_goal]);
459+
let (_, certainty) = ecx.evaluate_goal(new_goal)?;
460+
return ecx.make_canonical_response(certainty);
457461
}
458462
}
459463
}
@@ -466,7 +470,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
466470
tcx,
467471
ty::Binder::dummy(goal.predicate.with_self_ty(tcx, self_ty)),
468472
);
469-
return ecx.evaluate_all_and_make_canonical_response(vec![new_goal]);
473+
let (_, certainty) = ecx.evaluate_goal(new_goal)?;
474+
return ecx.make_canonical_response(certainty);
470475
}
471476
},
472477

@@ -479,9 +484,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
479484
),
480485
};
481486

482-
let nested_goals =
483-
ecx.infcx.eq(goal.param_env, goal.predicate.term.ty().unwrap(), metadata_ty)?;
484-
ecx.evaluate_all_and_make_canonical_response(nested_goals)
487+
ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, metadata_ty)
485488
})
486489
}
487490

0 commit comments

Comments
 (0)