Remove a back-compat hack on lazy TAIT
This commit is contained in:
parent
bd2e51a338
commit
c24f06354a
4 changed files with 28 additions and 31 deletions
|
@ -39,21 +39,19 @@ pub struct OpaqueTypeDecl<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
/// This is a backwards compatibility hack to prevent breaking changes from
|
pub fn replace_opaque_types_with_inference_vars(
|
||||||
/// lazy TAIT around RPIT handling.
|
|
||||||
pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>(
|
|
||||||
&self,
|
&self,
|
||||||
value: T,
|
ty: Ty<'tcx>,
|
||||||
body_id: HirId,
|
body_id: HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
code: ObligationCauseCode<'tcx>,
|
code: ObligationCauseCode<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> InferOk<'tcx, T> {
|
) -> InferOk<'tcx, Ty<'tcx>> {
|
||||||
if !value.has_opaque_types() {
|
if !ty.has_opaque_types() {
|
||||||
return InferOk { value, obligations: vec![] };
|
return InferOk { value: ty, obligations: vec![] };
|
||||||
}
|
}
|
||||||
let mut obligations = vec![];
|
let mut obligations = vec![];
|
||||||
let value = value.fold_with(&mut ty::fold::BottomUpFolder {
|
let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
|
||||||
tcx: self.tcx,
|
tcx: self.tcx,
|
||||||
lt_op: |lt| lt,
|
lt_op: |lt| lt,
|
||||||
ct_op: |ct| ct,
|
ct_op: |ct| ct,
|
||||||
|
|
|
@ -28,7 +28,6 @@ use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||||
use rustc_infer::traits::ObligationCauseCode;
|
|
||||||
use rustc_middle::traits::select::OverflowError;
|
use rustc_middle::traits::select::OverflowError;
|
||||||
use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::subst::Subst;
|
use rustc_middle::ty::subst::Subst;
|
||||||
|
@ -252,22 +251,10 @@ fn project_and_unify_type<'cx, 'tcx>(
|
||||||
Err(InProgress) => return ProjectAndUnifyResult::Recursive,
|
Err(InProgress) => return ProjectAndUnifyResult::Recursive,
|
||||||
};
|
};
|
||||||
debug!(?normalized, ?obligations, "project_and_unify_type result");
|
debug!(?normalized, ?obligations, "project_and_unify_type result");
|
||||||
let actual = obligation.predicate.term;
|
match infcx
|
||||||
// HACK: lazy TAIT would regress src/test/ui/impl-trait/nested-return-type2.rs, so we add
|
.at(&obligation.cause, obligation.param_env)
|
||||||
// a back-compat hack hat converts the RPITs into inference vars, just like they were before
|
.eq(normalized, obligation.predicate.term)
|
||||||
// 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,
|
|
||||||
ObligationCauseCode::MiscObligation,
|
|
||||||
obligation.param_env,
|
|
||||||
);
|
|
||||||
obligations.extend(new);
|
|
||||||
|
|
||||||
match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) {
|
|
||||||
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
|
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
|
||||||
obligations.extend(inferred_obligations);
|
obligations.extend(inferred_obligations);
|
||||||
ProjectAndUnifyResult::Holds(obligations)
|
ProjectAndUnifyResult::Holds(obligations)
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// check-pass
|
|
||||||
|
|
||||||
trait Duh {}
|
trait Duh {}
|
||||||
|
|
||||||
impl Duh for i32 {}
|
impl Duh for i32 {}
|
||||||
|
@ -20,11 +18,9 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
|
||||||
// the hidden type. We already have obligations registered on the inference
|
// the hidden type. We already have obligations registered on the inference
|
||||||
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
|
// var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque
|
||||||
// type does not implement `Duh`, even if its hidden type does.
|
// 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> {
|
fn foo() -> impl Trait<Assoc = impl Send> {
|
||||||
|
//~^ ERROR `impl Send: Duh` is not satisfied
|
||||||
|| 42
|
|| 42
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {}
|
||||||
}
|
|
||||||
|
|
16
src/test/ui/impl-trait/nested-return-type2.stderr
Normal file
16
src/test/ui/impl-trait/nested-return-type2.stderr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
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`
|
||||||
|
|
|
||||||
|
= help: the trait `Duh` is implemented for `i32`
|
||||||
|
note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2.rs:23:5: 23:10]`
|
||||||
|
--> $DIR/nested-return-type2.rs:12:31
|
||||||
|
|
|
||||||
|
LL | impl<R: Duh, F: FnMut() -> R> Trait for F {
|
||||||
|
| ^^^^^ ^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue