Skip to content

Commit 360edd6

Browse files
committed
Also use the RPIT back compat hack in trait projection
1 parent dc35d58 commit 360edd6

File tree

4 files changed

+29
-43
lines changed

4 files changed

+29
-43
lines changed

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,20 @@ pub struct OpaqueTypeDecl<'tcx> {
3939
}
4040

4141
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
42-
pub fn replace_opaque_types_with_inference_vars(
42+
/// This is a backwards compatibility hack to prevent breaking changes from
43+
/// lazy TAIT around RPIT handling.
44+
pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>(
4345
&self,
44-
ty: Ty<'tcx>,
46+
value: T,
4547
body_id: HirId,
4648
span: Span,
4749
param_env: ty::ParamEnv<'tcx>,
48-
) -> InferOk<'tcx, Ty<'tcx>> {
50+
) -> InferOk<'tcx, T> {
51+
if !value.has_opaque_types() {
52+
return InferOk { value, obligations: vec![] };
53+
}
4954
let mut obligations = vec![];
50-
let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
55+
let value = value.fold_with(&mut ty::fold::BottomUpFolder {
5156
tcx: self.tcx,
5257
lt_op: |lt| lt,
5358
ct_op: |ct| ct,

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,21 @@ fn project_and_unify_type<'cx, 'tcx>(
214214
Err(InProgress) => return Ok(Err(InProgress)),
215215
};
216216
debug!(?normalized, ?obligations, "project_and_unify_type result");
217-
match infcx
218-
.at(&obligation.cause, obligation.param_env)
219-
.eq(normalized, obligation.predicate.term)
220-
{
217+
let actual = obligation.predicate.term;
218+
// HACK: lazy TAIT would regress src/test/ui/impl-trait/nested-return-type2.rs, so we add
219+
// a back-compat hack hat converts the RPITs into inference vars, just like they were before
220+
// lazy TAIT.
221+
// This does not affect TAITs in general, as tested in the nested-return-type-tait* tests.
222+
let InferOk { value: actual, obligations: new } =
223+
selcx.infcx().replace_opaque_types_with_inference_vars(
224+
actual,
225+
obligation.cause.body_id,
226+
obligation.cause.span,
227+
obligation.param_env,
228+
);
229+
obligations.extend(new);
230+
231+
match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) {
221232
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
222233
obligations.extend(inferred_obligations);
223234
Ok(Ok(Some(obligations)))

src/test/ui/impl-trait/nested-return-type2.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
trait Duh {}
24

35
impl Duh for i32 {}
@@ -17,10 +19,10 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
1719
// created, causing the inference var to be set to `impl Send` instead of
1820
// the hidden type. We already have obligations registered on the inference
1921
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
20-
// type does not implement `Duh`, even if its hidden type does. So we error out.
22+
// type does not implement `Duh`, even if its hidden type does.
23+
// Lazy TAIT would error out, but we inserted a hack to make it work again,
24+
// keeping backwards compatibility.
2125
fn foo() -> impl Trait<Assoc = impl Send> {
22-
//~^ ERROR `impl Send: Duh` is not satisfied
23-
//~| ERROR `impl Send: Duh` is not satisfied
2426
|| 42
2527
}
2628

src/test/ui/impl-trait/nested-return-type2.stderr

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)