From 360edd611d3de389c09685097cd9944d61bc8f07 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 23 Feb 2022 13:34:39 +0000 Subject: [PATCH] Also use the RPIT back compat hack in trait projection --- .../rustc_infer/src/infer/opaque_types.rs | 13 +++++--- .../src/traits/project.rs | 19 ++++++++--- src/test/ui/impl-trait/nested-return-type2.rs | 8 +++-- .../ui/impl-trait/nested-return-type2.stderr | 32 ------------------- 4 files changed, 29 insertions(+), 43 deletions(-) delete mode 100644 src/test/ui/impl-trait/nested-return-type2.stderr diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 59aea2b2030..e8cd5988b96 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -39,15 +39,20 @@ pub struct OpaqueTypeDecl<'tcx> { } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - pub fn replace_opaque_types_with_inference_vars( + /// This is a backwards compatibility hack to prevent breaking changes from + /// lazy TAIT around RPIT handling. + pub fn replace_opaque_types_with_inference_vars>( &self, - ty: Ty<'tcx>, + value: T, body_id: HirId, span: Span, param_env: ty::ParamEnv<'tcx>, - ) -> InferOk<'tcx, Ty<'tcx>> { + ) -> InferOk<'tcx, T> { + if !value.has_opaque_types() { + return InferOk { value, obligations: vec![] }; + } let mut obligations = vec![]; - let value = ty.fold_with(&mut ty::fold::BottomUpFolder { + let value = value.fold_with(&mut ty::fold::BottomUpFolder { tcx: self.tcx, lt_op: |lt| lt, ct_op: |ct| ct, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index b61e6873571..d4ec677a0b1 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -214,10 +214,21 @@ fn project_and_unify_type<'cx, 'tcx>( Err(InProgress) => return Ok(Err(InProgress)), }; debug!(?normalized, ?obligations, "project_and_unify_type result"); - match infcx - .at(&obligation.cause, obligation.param_env) - .eq(normalized, obligation.predicate.term) - { + let actual = obligation.predicate.term; + // HACK: lazy TAIT would regress src/test/ui/impl-trait/nested-return-type2.rs, so we add + // a back-compat hack hat converts the RPITs into inference vars, just like they were before + // lazy TAIT. + // This does not affect TAITs in general, as tested in the nested-return-type-tait* tests. + let InferOk { value: actual, obligations: new } = + selcx.infcx().replace_opaque_types_with_inference_vars( + actual, + obligation.cause.body_id, + obligation.cause.span, + obligation.param_env, + ); + obligations.extend(new); + + match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) { Ok(InferOk { obligations: inferred_obligations, value: () }) => { obligations.extend(inferred_obligations); Ok(Ok(Some(obligations))) diff --git a/src/test/ui/impl-trait/nested-return-type2.rs b/src/test/ui/impl-trait/nested-return-type2.rs index 77a395afba7..39928d543e1 100644 --- a/src/test/ui/impl-trait/nested-return-type2.rs +++ b/src/test/ui/impl-trait/nested-return-type2.rs @@ -1,3 +1,5 @@ +// check-pass + trait Duh {} impl Duh for i32 {} @@ -17,10 +19,10 @@ impl R> Trait for F { // created, causing the inference var to be set to `impl Send` instead of // the hidden type. We already have obligations registered on the inference // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque -// type does not implement `Duh`, even if its hidden type does. So we error out. +// type does not implement `Duh`, even if its hidden type does. +// Lazy TAIT would error out, but we inserted a hack to make it work again, +// keeping backwards compatibility. fn foo() -> impl Trait { - //~^ ERROR `impl Send: Duh` is not satisfied - //~| ERROR `impl Send: Duh` is not satisfied || 42 } diff --git a/src/test/ui/impl-trait/nested-return-type2.stderr b/src/test/ui/impl-trait/nested-return-type2.stderr deleted file mode 100644 index be6c19795ae..00000000000 --- a/src/test/ui/impl-trait/nested-return-type2.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error[E0277]: the trait bound `impl Send: Duh` is not satisfied - --> $DIR/nested-return-type2.rs:21:13 - | -LL | fn foo() -> impl Trait { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Duh` is not implemented for `impl Send` - | -note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2.rs:24:5: 24:10]` - --> $DIR/nested-return-type2.rs:12:31 - | -LL | impl R> Trait for F { - | ^^^^^ ^ - -error[E0277]: the trait bound `impl Send: Duh` is not satisfied - --> $DIR/nested-return-type2.rs:21:43 - | -LL | fn foo() -> impl Trait { - | ___________________________________________^ -LL | | -LL | | -LL | | || 42 -LL | | } - | |_^ the trait `Duh` is not implemented for `impl Send` - | -note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2.rs:24:5: 24:10]` - --> $DIR/nested-return-type2.rs:12:31 - | -LL | impl R> Trait for F { - | ^^^^^ ^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`.