From 773fa7adbca745e86c59503e17d9d4c5b7dcc275 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 26 Jan 2022 21:47:03 -0800 Subject: [PATCH 1/2] Consolidate normalization in confirm_poly_trait_refs --- .../src/traits/select/confirmation.rs | 103 +++++------------- 1 file changed, 30 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 84bc7cdff2890..2579e4b317434 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -553,23 +553,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) .map_bound(|(trait_ref, _)| trait_ref); - let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| { - normalize_with_depth( - self, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - trait_ref, - ) - }); - - obligations.extend(self.confirm_poly_trait_refs( - obligation.cause.clone(), - obligation.param_env, - obligation.predicate.to_poly_trait_ref(), - trait_ref, - )?); - Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested: obligations }) + let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; + Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested }) } fn confirm_trait_alias_candidate( @@ -616,26 +601,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate"); let trait_ref = self.generator_trait_ref_unnormalized(obligation, substs); - let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| { - normalize_with_depth( - self, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - trait_ref, - ) - }); - debug!(?trait_ref, ?obligations, "generator candidate obligations"); - - obligations.extend(self.confirm_poly_trait_refs( - obligation.cause.clone(), - obligation.param_env, - obligation.predicate.to_poly_trait_ref(), - trait_ref, - )?); + let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; + debug!(?trait_ref, ?nested, "generator candidate obligations"); - Ok(ImplSourceGeneratorData { generator_def_id, substs, nested: obligations }) + Ok(ImplSourceGeneratorData { generator_def_id, substs, nested }) } #[instrument(skip(self), level = "debug")] @@ -657,44 +627,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => bug!("closure candidate for non-closure {:?}", obligation), }; - let obligation_predicate = obligation.predicate; - let Normalized { value: obligation_predicate, mut obligations } = - ensure_sufficient_stack(|| { - normalize_with_depth( - self, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - obligation_predicate, - ) - }); - let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs); - let Normalized { value: trait_ref, obligations: trait_ref_obligations } = - ensure_sufficient_stack(|| { - normalize_with_depth( - self, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - trait_ref, - ) - }); + let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; - debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations"); - - obligations.extend(trait_ref_obligations); - obligations.extend(self.confirm_poly_trait_refs( - obligation.cause.clone(), - obligation.param_env, - obligation_predicate.to_poly_trait_ref(), - trait_ref, - )?); + debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations"); // FIXME: Chalk if !self.tcx().sess.opts.debugging_opts.chalk { - obligations.push(Obligation::new( + nested.push(Obligation::new( obligation.cause.clone(), obligation.param_env, ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)) @@ -702,7 +643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { )); } - Ok(ImplSourceClosureData { closure_def_id, substs, nested: obligations }) + Ok(ImplSourceClosureData { closure_def_id, substs, nested }) } /// In the case of closure types and fn pointers, @@ -733,15 +674,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { #[instrument(skip(self), level = "trace")] fn confirm_poly_trait_refs( &mut self, - obligation_cause: ObligationCause<'tcx>, - obligation_param_env: ty::ParamEnv<'tcx>, - obligation_trait_ref: ty::PolyTraitRef<'tcx>, + obligation: &TraitObligation<'tcx>, expected_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result>, SelectionError<'tcx>> { + let obligation_trait_ref = obligation.predicate.to_poly_trait_ref(); + // Normalize the obligation and expected trait refs together, because why not + let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } = + ensure_sufficient_stack(|| { + self.infcx.commit_unconditionally(|_| { + normalize_with_depth( + self, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + (obligation_trait_ref, expected_trait_ref), + ) + }) + }); + self.infcx - .at(&obligation_cause, obligation_param_env) + .at(&obligation.cause, obligation.param_env) .sup(obligation_trait_ref, expected_trait_ref) - .map(|InferOk { obligations, .. }| obligations) + .map(|InferOk { mut obligations, .. }| { + obligations.extend(nested); + obligations + }) .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e)) } From b59c958ba6d1a6834c8915ce8146f9a8e81557b6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 17 Feb 2022 17:21:48 -0800 Subject: [PATCH 2/2] Bless up --- .../bugs/issue-88382.stderr | 8 ++-- .../higher-rank-trait-bounds/issue-60283.rs | 4 +- .../issue-60283.stderr | 42 ------------------- 3 files changed, 6 insertions(+), 48 deletions(-) delete mode 100644 src/test/ui/higher-rank-trait-bounds/issue-60283.stderr diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr index d06c3ec8de75e..ce196dcbd863d 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr +++ b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr @@ -2,18 +2,18 @@ error[E0631]: type mismatch in function arguments --> $DIR/issue-88382.rs:28:40 | LL | do_something(SomeImplementation(), test); - | ------------ ^^^^ expected signature of `for<'a> fn(&mut ::Iterator<'a>) -> _` + | ------------ ^^^^ expected signature of `for<'r> fn(&'r mut std::iter::Empty) -> _` | | | required by a bound introduced by this call ... LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} - | ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty) -> _` + | ------------------------------------------------- found signature of `for<'r, 'a> fn(&'r mut <_ as Iterable>::Iterator<'a>) -> _` | note: required by a bound in `do_something` - --> $DIR/issue-88382.rs:22:56 + --> $DIR/issue-88382.rs:22:48 | LL | fn do_something(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something` error: aborting due to previous error diff --git a/src/test/ui/higher-rank-trait-bounds/issue-60283.rs b/src/test/ui/higher-rank-trait-bounds/issue-60283.rs index c63b1544a5379..05315b3f9f5e9 100644 --- a/src/test/ui/higher-rank-trait-bounds/issue-60283.rs +++ b/src/test/ui/higher-rank-trait-bounds/issue-60283.rs @@ -1,3 +1,5 @@ +// check-pass + pub trait Trait<'a> { type Item; } @@ -15,6 +17,4 @@ where fn main() { foo((), drop) - //~^ ERROR type mismatch in function arguments - //~| ERROR size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time } diff --git a/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr b/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr deleted file mode 100644 index 34893cd8f19d9..0000000000000 --- a/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0631]: type mismatch in function arguments - --> $DIR/issue-60283.rs:17:13 - | -LL | foo((), drop) - | --- ^^^^ - | | | - | | expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _` - | | found signature of `fn(()) -> _` - | required by a bound introduced by this call - | -note: required by a bound in `foo` - --> $DIR/issue-60283.rs:12:16 - | -LL | pub fn foo(_: T, _: F) - | --- required by a bound in this -... -LL | F: for<'a> FnMut(>::Item), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - -error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time - --> $DIR/issue-60283.rs:17:13 - | -LL | foo((), drop) - | --- ^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call - | - = help: the trait `Sized` is not implemented for `<() as Trait<'_>>::Item` -note: required by a bound in `std::mem::drop` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | -LL | pub fn drop(_x: T) {} - | ^ required by this bound in `std::mem::drop` -help: consider further restricting the associated type - | -LL | fn main() where <() as Trait<'_>>::Item: Sized { - | ++++++++++++++++++++++++++++++++++++ - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0277, E0631. -For more information about an error, try `rustc --explain E0277`.