Auto merge of #90948 - oli-obk:🧹, r=nikomatsakis
Actually instantiate the opaque type when checking bounds Before this change, `instantiate_opaque_types` was a no-op, because it only works relative to the defined opaque type inference anchor. If it is a no-op, the for loop will not actually have anything to iterate over, and thus nothing is checked at all.
This commit is contained in:
commit
1409c015b4
2 changed files with 49 additions and 21 deletions
|
@ -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
|
/// Without this check the above code is incorrectly accepted: we would ICE if
|
||||||
/// some tried, for example, to clone an `Option<X<&mut ()>>`.
|
/// some tried, for example, to clone an `Option<X<&mut ()>>`.
|
||||||
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
fn check_opaque_meets_bounds<'tcx>(
|
fn check_opaque_meets_bounds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
|
@ -633,17 +634,14 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
span: Span,
|
span: Span,
|
||||||
origin: &hir::OpaqueTyOrigin,
|
origin: &hir::OpaqueTyOrigin,
|
||||||
) {
|
) {
|
||||||
match origin {
|
|
||||||
// Checked when type checking the function containing them.
|
|
||||||
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return,
|
|
||||||
// Can have different predicates to their defining use
|
|
||||||
hir::OpaqueTyOrigin::TyAlias => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
let param_env = tcx.param_env(def_id);
|
let defining_use_anchor = match *origin {
|
||||||
|
hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
|
||||||
|
hir::OpaqueTyOrigin::TyAlias => def_id,
|
||||||
|
};
|
||||||
|
let param_env = tcx.param_env(defining_use_anchor);
|
||||||
|
|
||||||
tcx.infer_ctxt().enter(move |infcx| {
|
tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).enter(move |infcx| {
|
||||||
let inh = Inherited::new(infcx, def_id);
|
let inh = Inherited::new(infcx, def_id);
|
||||||
let infcx = &inh.infcx;
|
let infcx = &inh.infcx;
|
||||||
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
|
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
|
||||||
|
@ -656,16 +654,15 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
|
|
||||||
let opaque_type_map = infcx.inner.borrow().opaque_types.clone();
|
let opaque_type_map = infcx.inner.borrow().opaque_types.clone();
|
||||||
for (OpaqueTypeKey { def_id, substs }, opaque_defn) in opaque_type_map {
|
for (OpaqueTypeKey { def_id, substs }, opaque_defn) in opaque_type_map {
|
||||||
match infcx
|
let hidden_type = tcx.type_of(def_id).subst(tcx, substs);
|
||||||
.at(&misc_cause, param_env)
|
trace!(?hidden_type);
|
||||||
.eq(opaque_defn.concrete_ty, tcx.type_of(def_id).subst(tcx, substs))
|
match infcx.at(&misc_cause, param_env).eq(opaque_defn.concrete_ty, hidden_type) {
|
||||||
{
|
|
||||||
Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok),
|
Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok),
|
||||||
Err(ty_err) => tcx.sess.delay_span_bug(
|
Err(ty_err) => tcx.sess.delay_span_bug(
|
||||||
opaque_defn.definition_span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
"could not unify `{}` with revealed type:\n{}",
|
"could not check bounds on revealed type `{}`:\n{}",
|
||||||
opaque_defn.concrete_ty, ty_err,
|
hidden_type, ty_err,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -678,10 +675,17 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
infcx.report_fulfillment_errors(&errors, None, false);
|
infcx.report_fulfillment_errors(&errors, None, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, resolve all regions. This catches wily misuses of
|
match origin {
|
||||||
// lifetime parameters.
|
// Checked when type checking the function containing them.
|
||||||
let fcx = FnCtxt::new(&inh, param_env, hir_id);
|
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return,
|
||||||
fcx.regionck_item(hir_id, span, FxHashSet::default());
|
// Can have different predicates to their defining use
|
||||||
|
hir::OpaqueTyOrigin::TyAlias => {
|
||||||
|
// Finally, resolve all regions. This catches wily misuses of
|
||||||
|
// lifetime parameters.
|
||||||
|
let fcx = FnCtxt::new(&inh, param_env, hir_id);
|
||||||
|
fcx.regionck_item(hir_id, span, FxHashSet::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,5 +10,29 @@ error: higher-ranked subtype error
|
||||||
LL | |x| x
|
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`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue