Actually instantiate the opaque type when checking bounds

Before this change, `instantiate_opaque_types` was a no-op
This commit is contained in:
Oli Scherer 2021-11-16 13:46:03 +00:00
parent 1d01550f7e
commit 5d07a6ceb4
2 changed files with 33 additions and 9 deletions

View File

@ -626,6 +626,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
///
/// Without this check the above code is incorrectly accepted: we would ICE if
/// some tried, for example, to clone an `Option<X<&mut ()>>`.
#[instrument(skip(tcx))]
fn check_opaque_meets_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
@ -643,7 +644,7 @@ fn check_opaque_meets_bounds<'tcx>(
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let param_env = tcx.param_env(def_id);
tcx.infer_ctxt().enter(move |infcx| {
tcx.infer_ctxt().with_opaque_type_inference(def_id).enter(move |infcx| {
let inh = Inherited::new(infcx, def_id);
let infcx = &inh.infcx;
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
@ -656,16 +657,15 @@ fn check_opaque_meets_bounds<'tcx>(
let opaque_type_map = infcx.inner.borrow().opaque_types.clone();
for (OpaqueTypeKey { def_id, substs }, opaque_defn) in opaque_type_map {
match infcx
.at(&misc_cause, param_env)
.eq(opaque_defn.concrete_ty, tcx.type_of(def_id).subst(tcx, substs))
{
let hidden_type = tcx.type_of(def_id).subst(tcx, substs);
trace!(?hidden_type);
match infcx.at(&misc_cause, param_env).eq(opaque_defn.concrete_ty, hidden_type) {
Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok),
Err(ty_err) => tcx.sess.delay_span_bug(
opaque_defn.definition_span,
span,
&format!(
"could not unify `{}` with revealed type:\n{}",
opaque_defn.concrete_ty, ty_err,
"could not check bounds on revealed type `{}`:\n{}",
hidden_type, ty_err,
),
),
}

View File

@ -10,5 +10,29 @@ error: higher-ranked subtype error
LL | |x| x
| ^^^^^
error: aborting due to 2 previous errors
error[E0308]: mismatched types
--> $DIR/issue-57611-trait-alias.rs:17:16
|
LL | type Bar = impl Baz<Self, Self>;
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected type `for<'r> Fn<(&'r X,)>`
found type `Fn<(&'static X,)>`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-57611-trait-alias.rs:21:9
|
LL | |x| x
| ^^^^^
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-57611-trait-alias.rs:17:16
|
LL | type Bar = impl Baz<Self, Self>;
| ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'static X) -> &'static X` must implement `FnOnce<(&'0 X,)>`, for any lifetime `'0`...
= note: ...but it actually implements `FnOnce<(&'static X,)>`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.