Also use the RPIT back compat hack in trait projection
This commit is contained in:
parent
dc35d584a9
commit
360edd611d
@ -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<T: TypeFoldable<'tcx>>(
|
||||
&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,
|
||||
|
@ -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)))
|
||||
|
@ -1,3 +1,5 @@
|
||||
// check-pass
|
||||
|
||||
trait Duh {}
|
||||
|
||||
impl Duh for i32 {}
|
||||
@ -17,10 +19,10 @@ impl<R: Duh, F: FnMut() -> 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<Assoc = impl Send> {
|
||||
//~^ ERROR `impl Send: Duh` is not satisfied
|
||||
//~| ERROR `impl Send: Duh` is not satisfied
|
||||
|| 42
|
||||
}
|
||||
|
||||
|
@ -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<Assoc = impl Send> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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: Duh, F: FnMut() -> 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<Assoc = impl Send> {
|
||||
| ___________________________________________^
|
||||
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: Duh, F: FnMut() -> R> Trait for F {
|
||||
| ^^^^^ ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
x
Reference in New Issue
Block a user