use rustc_infer::infer::{
InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
};
+use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::AssertKind;
)
.unwrap();
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
+ // Check that RPITs are only constrained in their outermost
+ // function, otherwise report a mismatched types error.
+ if let hir::Node::Item(hir::Item {
+ kind:
+ hir::ItemKind::OpaqueTy(hir::OpaqueTy {
+ origin:
+ hir::OpaqueTyOrigin::AsyncFn(parent)
+ | hir::OpaqueTyOrigin::FnReturn(parent),
+ ..
+ }),
+ ..
+ }) = infcx.tcx.hir().get_by_def_id(opaque_type_key.def_id.expect_local()) &&
+ parent.to_def_id() != body.source.def_id()
+ {
+ infcx
+ .report_mismatched_types(
+ &ObligationCause::misc(
+ hidden_type.span,
+ infcx.tcx.hir().local_def_id_to_hir_id(
+ body.source.def_id().expect_local(),
+ ),
+ ),
+ infcx.tcx.mk_opaque(opaque_type_key.def_id, opaque_type_key.substs),
+ hidden_type.ty,
+ ty::error::TypeError::Mismatch,
+ )
+ .emit();
+ }
trace!(
"finalized opaque type {:?} to {:#?}",
opaque_type_key,
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-99073-2.rs:9:22
+ |
+LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display {
+ | ------------ the expected opaque type
+LL | let f = || {
+LL | let i: u32 = test::<i32>(-1, false);
+ | ^^^^^^^^^^^^^^^^^^^^^^ types differ
+ |
+ = note: expected opaque type `impl std::fmt::Display`
+ found type `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-99073.rs:6:13
+ |
+LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
+ | --------- the expected opaque type
+LL | move || f(fix(&f))
+ | ^^^^^^^^^^ types differ
+ |
+ = note: expected opaque type `impl Fn()`
+ found type parameter `G`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.