Skip to content

Commit 1409c01

Browse files
committed
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.
2 parents 2e2c86e + 15f7e81 commit 1409c01

File tree

2 files changed

+49
-21
lines changed

2 files changed

+49
-21
lines changed

compiler/rustc_typeck/src/check/check.rs

+24-20
Original file line numberDiff line numberDiff line change
@@ -626,24 +626,22 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
626626
///
627627
/// Without this check the above code is incorrectly accepted: we would ICE if
628628
/// some tried, for example, to clone an `Option<X<&mut ()>>`.
629+
#[instrument(level = "debug", skip(tcx))]
629630
fn check_opaque_meets_bounds<'tcx>(
630631
tcx: TyCtxt<'tcx>,
631632
def_id: LocalDefId,
632633
substs: SubstsRef<'tcx>,
633634
span: Span,
634635
origin: &hir::OpaqueTyOrigin,
635636
) {
636-
match origin {
637-
// Checked when type checking the function containing them.
638-
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return,
639-
// Can have different predicates to their defining use
640-
hir::OpaqueTyOrigin::TyAlias => {}
641-
}
642-
643637
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
644-
let param_env = tcx.param_env(def_id);
638+
let defining_use_anchor = match *origin {
639+
hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
640+
hir::OpaqueTyOrigin::TyAlias => def_id,
641+
};
642+
let param_env = tcx.param_env(defining_use_anchor);
645643

646-
tcx.infer_ctxt().enter(move |infcx| {
644+
tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).enter(move |infcx| {
647645
let inh = Inherited::new(infcx, def_id);
648646
let infcx = &inh.infcx;
649647
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
@@ -656,16 +654,15 @@ fn check_opaque_meets_bounds<'tcx>(
656654

657655
let opaque_type_map = infcx.inner.borrow().opaque_types.clone();
658656
for (OpaqueTypeKey { def_id, substs }, opaque_defn) in opaque_type_map {
659-
match infcx
660-
.at(&misc_cause, param_env)
661-
.eq(opaque_defn.concrete_ty, tcx.type_of(def_id).subst(tcx, substs))
662-
{
657+
let hidden_type = tcx.type_of(def_id).subst(tcx, substs);
658+
trace!(?hidden_type);
659+
match infcx.at(&misc_cause, param_env).eq(opaque_defn.concrete_ty, hidden_type) {
663660
Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok),
664661
Err(ty_err) => tcx.sess.delay_span_bug(
665-
opaque_defn.definition_span,
662+
span,
666663
&format!(
667-
"could not unify `{}` with revealed type:\n{}",
668-
opaque_defn.concrete_ty, ty_err,
664+
"could not check bounds on revealed type `{}`:\n{}",
665+
hidden_type, ty_err,
669666
),
670667
),
671668
}
@@ -678,10 +675,17 @@ fn check_opaque_meets_bounds<'tcx>(
678675
infcx.report_fulfillment_errors(&errors, None, false);
679676
}
680677

681-
// Finally, resolve all regions. This catches wily misuses of
682-
// lifetime parameters.
683-
let fcx = FnCtxt::new(&inh, param_env, hir_id);
684-
fcx.regionck_item(hir_id, span, FxHashSet::default());
678+
match origin {
679+
// Checked when type checking the function containing them.
680+
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return,
681+
// Can have different predicates to their defining use
682+
hir::OpaqueTyOrigin::TyAlias => {
683+
// Finally, resolve all regions. This catches wily misuses of
684+
// lifetime parameters.
685+
let fcx = FnCtxt::new(&inh, param_env, hir_id);
686+
fcx.regionck_item(hir_id, span, FxHashSet::default());
687+
}
688+
}
685689
});
686690
}
687691

src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr

+25-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,29 @@ error: higher-ranked subtype error
1010
LL | |x| x
1111
| ^^^^^
1212

13-
error: aborting due to 2 previous errors
13+
error[E0308]: mismatched types
14+
--> $DIR/issue-57611-trait-alias.rs:17:16
15+
|
16+
LL | type Bar = impl Baz<Self, Self>;
17+
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
18+
|
19+
= note: expected type `for<'r> Fn<(&'r X,)>`
20+
found type `Fn<(&'static X,)>`
21+
note: this closure does not fulfill the lifetime requirements
22+
--> $DIR/issue-57611-trait-alias.rs:21:9
23+
|
24+
LL | |x| x
25+
| ^^^^^
26+
27+
error: implementation of `FnOnce` is not general enough
28+
--> $DIR/issue-57611-trait-alias.rs:17:16
29+
|
30+
LL | type Bar = impl Baz<Self, Self>;
31+
| ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
32+
|
33+
= note: closure with signature `fn(&'static X) -> &'static X` must implement `FnOnce<(&'0 X,)>`, for any lifetime `'0`...
34+
= note: ...but it actually implements `FnOnce<(&'static X,)>`
35+
36+
error: aborting due to 4 previous errors
1437

38+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)