Skip to content

Commit a924ef7

Browse files
committed
Auto merge of #94108 - compiler-errors:just-confirmation-normalization, r=jackh726
Normalize obligation and expected trait_refs in confirm_poly_trait_refs Consolidate normalization the obligation and expected trait refs in `confirm_poly_trait_refs`. Also, _always_ normalize these trait refs -- we were already normalizing the obligation trait ref when confirming closure and generator candidates, but this does it for fn pointer confirmation as well. This presumably does more work in the case that the obligation's trait ref is already normalized, but we can see from the perf runs in #94070, it actually (paradoxically, perhaps) improves performance when paired with logic that normalizes projections in fulfillment loop.
2 parents 026d8ce + b59c958 commit a924ef7

File tree

4 files changed

+36
-121
lines changed

4 files changed

+36
-121
lines changed

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+30-73
Original file line numberDiff line numberDiff line change
@@ -553,23 +553,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
553553
)
554554
.map_bound(|(trait_ref, _)| trait_ref);
555555

556-
let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
557-
normalize_with_depth(
558-
self,
559-
obligation.param_env,
560-
obligation.cause.clone(),
561-
obligation.recursion_depth + 1,
562-
trait_ref,
563-
)
564-
});
565-
566-
obligations.extend(self.confirm_poly_trait_refs(
567-
obligation.cause.clone(),
568-
obligation.param_env,
569-
obligation.predicate.to_poly_trait_ref(),
570-
trait_ref,
571-
)?);
572-
Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested: obligations })
556+
let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
557+
Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
573558
}
574559

575560
fn confirm_trait_alias_candidate(
@@ -616,26 +601,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
616601
debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
617602

618603
let trait_ref = self.generator_trait_ref_unnormalized(obligation, substs);
619-
let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
620-
normalize_with_depth(
621-
self,
622-
obligation.param_env,
623-
obligation.cause.clone(),
624-
obligation.recursion_depth + 1,
625-
trait_ref,
626-
)
627-
});
628604

629-
debug!(?trait_ref, ?obligations, "generator candidate obligations");
630-
631-
obligations.extend(self.confirm_poly_trait_refs(
632-
obligation.cause.clone(),
633-
obligation.param_env,
634-
obligation.predicate.to_poly_trait_ref(),
635-
trait_ref,
636-
)?);
605+
let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
606+
debug!(?trait_ref, ?nested, "generator candidate obligations");
637607

638-
Ok(ImplSourceGeneratorData { generator_def_id, substs, nested: obligations })
608+
Ok(ImplSourceGeneratorData { generator_def_id, substs, nested })
639609
}
640610

641611
#[instrument(skip(self), level = "debug")]
@@ -657,52 +627,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
657627
_ => bug!("closure candidate for non-closure {:?}", obligation),
658628
};
659629

660-
let obligation_predicate = obligation.predicate;
661-
let Normalized { value: obligation_predicate, mut obligations } =
662-
ensure_sufficient_stack(|| {
663-
normalize_with_depth(
664-
self,
665-
obligation.param_env,
666-
obligation.cause.clone(),
667-
obligation.recursion_depth + 1,
668-
obligation_predicate,
669-
)
670-
});
671-
672630
let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
673-
let Normalized { value: trait_ref, obligations: trait_ref_obligations } =
674-
ensure_sufficient_stack(|| {
675-
normalize_with_depth(
676-
self,
677-
obligation.param_env,
678-
obligation.cause.clone(),
679-
obligation.recursion_depth + 1,
680-
trait_ref,
681-
)
682-
});
631+
let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
683632

684-
debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
685-
686-
obligations.extend(trait_ref_obligations);
687-
obligations.extend(self.confirm_poly_trait_refs(
688-
obligation.cause.clone(),
689-
obligation.param_env,
690-
obligation_predicate.to_poly_trait_ref(),
691-
trait_ref,
692-
)?);
633+
debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
693634

694635
// FIXME: Chalk
695636

696637
if !self.tcx().sess.opts.debugging_opts.chalk {
697-
obligations.push(Obligation::new(
638+
nested.push(Obligation::new(
698639
obligation.cause.clone(),
699640
obligation.param_env,
700641
ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind))
701642
.to_predicate(self.tcx()),
702643
));
703644
}
704645

705-
Ok(ImplSourceClosureData { closure_def_id, substs, nested: obligations })
646+
Ok(ImplSourceClosureData { closure_def_id, substs, nested })
706647
}
707648

708649
/// In the case of closure types and fn pointers,
@@ -733,15 +674,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
733674
#[instrument(skip(self), level = "trace")]
734675
fn confirm_poly_trait_refs(
735676
&mut self,
736-
obligation_cause: ObligationCause<'tcx>,
737-
obligation_param_env: ty::ParamEnv<'tcx>,
738-
obligation_trait_ref: ty::PolyTraitRef<'tcx>,
677+
obligation: &TraitObligation<'tcx>,
739678
expected_trait_ref: ty::PolyTraitRef<'tcx>,
740679
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
680+
let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
681+
// Normalize the obligation and expected trait refs together, because why not
682+
let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } =
683+
ensure_sufficient_stack(|| {
684+
self.infcx.commit_unconditionally(|_| {
685+
normalize_with_depth(
686+
self,
687+
obligation.param_env,
688+
obligation.cause.clone(),
689+
obligation.recursion_depth + 1,
690+
(obligation_trait_ref, expected_trait_ref),
691+
)
692+
})
693+
});
694+
741695
self.infcx
742-
.at(&obligation_cause, obligation_param_env)
696+
.at(&obligation.cause, obligation.param_env)
743697
.sup(obligation_trait_ref, expected_trait_ref)
744-
.map(|InferOk { obligations, .. }| obligations)
698+
.map(|InferOk { mut obligations, .. }| {
699+
obligations.extend(nested);
700+
obligations
701+
})
745702
.map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
746703
}
747704

src/test/ui/generic-associated-types/bugs/issue-88382.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ error[E0631]: type mismatch in function arguments
22
--> $DIR/issue-88382.rs:28:40
33
|
44
LL | do_something(SomeImplementation(), test);
5-
| ------------ ^^^^ expected signature of `for<'a> fn(&mut <SomeImplementation as Iterable>::Iterator<'a>) -> _`
5+
| ------------ ^^^^ expected signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
66
| |
77
| required by a bound introduced by this call
88
...
99
LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
10-
| ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
10+
| ------------------------------------------------- found signature of `for<'r, 'a> fn(&'r mut <_ as Iterable>::Iterator<'a>) -> _`
1111
|
1212
note: required by a bound in `do_something`
13-
--> $DIR/issue-88382.rs:22:56
13+
--> $DIR/issue-88382.rs:22:48
1414
|
1515
LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
1717

1818
error: aborting due to previous error
1919

src/test/ui/higher-rank-trait-bounds/issue-60283.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
pub trait Trait<'a> {
24
type Item;
35
}
@@ -15,6 +17,4 @@ where
1517

1618
fn main() {
1719
foo((), drop)
18-
//~^ ERROR type mismatch in function arguments
19-
//~| ERROR size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
2020
}

src/test/ui/higher-rank-trait-bounds/issue-60283.stderr

-42
This file was deleted.

0 commit comments

Comments
 (0)