Skip to content

Commit f771696

Browse files
author
Markus Westerlind
committed
perf: No need to resolve variables in fulfillment
1 parent 22abfb6 commit f771696

File tree

1 file changed

+43
-38
lines changed
  • compiler/rustc_trait_selection/src/traits

1 file changed

+43
-38
lines changed

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,9 @@ struct FulfillProcessor<'a, 'b, 'tcx> {
260260
register_region_obligations: bool,
261261
}
262262

263-
fn mk_pending(
264-
infcx: &InferCtxt<'_, 'tcx>,
265-
os: Vec<PredicateObligation<'tcx>>,
266-
) -> Vec<PendingPredicateObligation<'tcx>> {
263+
fn mk_pending(os: Vec<PredicateObligation<'tcx>>) -> Vec<PendingPredicateObligation<'tcx>> {
267264
os.into_iter()
268-
.map(|mut o| {
269-
o.predicate = infcx.resolve_vars_if_possible(&o.predicate);
270-
PendingPredicateObligation { obligation: o, stalled_on: vec![] }
271-
})
265+
.map(|o| PendingPredicateObligation { obligation: o, stalled_on: vec![] })
272266
.collect()
273267
}
274268

@@ -412,29 +406,38 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
412406
) {
413407
None => {
414408
pending_obligation.stalled_on.clear();
415-
pending_obligation.stalled_on.push(TyOrConstInferVar::maybe_from_generic_arg(arg).unwrap());
409+
pending_obligation.stalled_on.push(infcx.root_ty_or_const(
410+
TyOrConstInferVar::maybe_from_generic_arg(arg).unwrap(),
411+
));
416412
ProcessResult::Unchanged
417413
}
418414
Some(os) => ProcessResult::Changed(mk_pending(os)),
419415
}
420416
}
421417

422-
&ty::PredicateKind::WellFormed(arg) => {
423-
match wf::obligations(
424-
self.selcx.infcx(),
425-
obligation.param_env,
426-
obligation.cause.body_id,
427-
arg,
428-
obligation.cause.span,
429-
) {
430-
None => {
431-
pending_obligation.stalled_on.clear();
432-
pending_obligation
433-
.stalled_on
434-
.push(TyOrConstInferVar::maybe_from_generic_arg(arg).unwrap());
435-
ProcessResult::Unchanged
418+
ty::PredicateAtom::Subtype(subtype) => {
419+
match self.selcx.infcx().subtype_predicate(
420+
&obligation.cause,
421+
obligation.param_env,
422+
Binder::dummy(subtype),
423+
) {
424+
None => {
425+
// None means that both are unresolved.
426+
pending_obligation.stalled_on.clear();
427+
pending_obligation.stalled_on.push(root_ty_or_const_var(subtype.a));
428+
pending_obligation.stalled_on.push(root_ty_or_const_var(subtype.b));
429+
ProcessResult::Unchanged
430+
}
431+
Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
432+
Some(Err(err)) => {
433+
let expected_found =
434+
ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b);
435+
ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
436+
expected_found,
437+
err,
438+
))
439+
}
436440
}
437-
Some(os) => ProcessResult::Changed(mk_pending(infcx, os)),
438441
}
439442

440443
ty::PredicateAtom::ConstEvaluatable(def_id, substs) => {
@@ -447,10 +450,12 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
447450
) {
448451
Ok(()) => ProcessResult::Changed(vec![]),
449452
Err(ErrorHandled::TooGeneric) => {
450-
pending_obligation.stalled_on = substs
451-
.iter()
452-
.filter_map(|ty| TyOrConstInferVar::maybe_from_generic_arg(ty))
453-
.collect();
453+
pending_obligation.stalled_on.extend(
454+
substs
455+
.iter()
456+
.filter_map(|ty| TyOrConstInferVar::maybe_from_generic_arg(ty))
457+
.map(|ty| infcx.root_ty_or_const(ty)),
458+
);
454459
ProcessResult::Unchanged
455460
}
456461
Err(e) => ProcessResult::Error(CodeSelectionError(ConstEvalFailure(e))),
@@ -492,13 +497,13 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
492497
) {
493498
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)),
494499
Err(ErrorHandled::TooGeneric) => {
495-
stalled_on.append(
496-
&mut substs
497-
.iter()
500+
stalled_on.extend(
501+
substs
502+
.types()
498503
.filter_map(|arg| {
499504
TyOrConstInferVar::maybe_from_generic_arg(arg)
500505
})
501-
.collect(),
506+
.map(|ty| infcx.root_ty_or_const(ty)),
502507
);
503508
Err(ErrorHandled::TooGeneric)
504509
}
@@ -596,7 +601,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
596601
&mut self,
597602
obligation: &PredicateObligation<'tcx>,
598603
trait_obligation: TraitObligation<'tcx>,
599-
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
604+
stalled_on: &mut Vec<TyOrConstInferVar>,
600605
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
601606
let infcx = self.selcx.infcx();
602607
if obligation.predicate.is_global() {
@@ -623,10 +628,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
623628
// only reason we can fail to make progress on
624629
// trait selection is because we don't have enough
625630
// information about the types in the trait.
626-
*stalled_on = trait_ref_infer_vars(
631+
stalled_on.extend(trait_ref_infer_vars(
627632
self.selcx,
628633
trait_obligation.predicate.map_bound(|pred| pred.trait_ref),
629-
);
634+
));
630635

631636
debug!(
632637
"process_predicate: pending obligation {:?} now stalled on {:?}",
@@ -647,16 +652,16 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
647652
fn process_projection_obligation(
648653
&mut self,
649654
project_obligation: PolyProjectionObligation<'tcx>,
650-
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
655+
stalled_on: &mut Vec<TyOrConstInferVar>,
651656
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
652657
let tcx = self.selcx.tcx();
653658
match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
654659
Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
655660
Ok(Ok(None)) => {
656-
*stalled_on = trait_ref_infer_vars(
661+
stalled_on.extend(trait_ref_infer_vars(
657662
self.selcx,
658663
project_obligation.predicate.to_poly_trait_ref(tcx),
659-
);
664+
));
660665
ProcessResult::Unchanged
661666
}
662667
// Let the caller handle the recursion

0 commit comments

Comments
 (0)