diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index fd7b3a55dfb97..3ac2dfd866957 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -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>`. +#[instrument(level = "debug", skip(tcx))] fn check_opaque_meets_bounds<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, @@ -633,17 +634,14 @@ fn check_opaque_meets_bounds<'tcx>( span: Span, 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 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 infcx = &inh.infcx; 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(); 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, ), ), } @@ -678,10 +675,17 @@ fn check_opaque_meets_bounds<'tcx>( infcx.report_fulfillment_errors(&errors, None, false); } - // 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()); + 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 => { + // 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()); + } + } }); } diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr index 8c9cb742fac91..a4ccae4eb7ed9 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr @@ -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; + | ^^^^^^^^^^^^^^^^^^^^ 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; + | ^^^^^^^^^^^^^^^^^^^^ 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`.