@@ -21,6 +21,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
2121use rustc_infer:: infer:: {
2222 InferCtxt , InferOk , LateBoundRegion , LateBoundRegionConversionTime , NllRegionVariableOrigin ,
2323} ;
24+ use rustc_infer:: traits:: ObligationCause ;
2425use rustc_middle:: mir:: tcx:: PlaceTy ;
2526use rustc_middle:: mir:: visit:: { NonMutatingUseContext , PlaceContext , Visitor } ;
2627use rustc_middle:: mir:: AssertKind ;
@@ -224,6 +225,34 @@ pub(crate) fn type_check<'mir, 'tcx>(
224225 )
225226 . unwrap ( ) ;
226227 let mut hidden_type = infcx. resolve_vars_if_possible ( decl. hidden_type ) ;
228+ // Check that RPITs are only constrained in their outermost
229+ // function, otherwise report a mismatched types error.
230+ if let hir:: Node :: Item ( hir:: Item {
231+ kind :
232+ hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy {
233+ origin :
234+ hir:: OpaqueTyOrigin :: AsyncFn ( parent)
235+ | hir:: OpaqueTyOrigin :: FnReturn ( parent) ,
236+ ..
237+ } ) ,
238+ ..
239+ } ) = infcx. tcx . hir ( ) . get_by_def_id ( opaque_type_key. def_id . expect_local ( ) ) &&
240+ parent. to_def_id ( ) != body. source . def_id ( )
241+ {
242+ infcx
243+ . report_mismatched_types (
244+ & ObligationCause :: misc (
245+ hidden_type. span ,
246+ infcx. tcx . hir ( ) . local_def_id_to_hir_id (
247+ body. source . def_id ( ) . expect_local ( ) ,
248+ ) ,
249+ ) ,
250+ infcx. tcx . mk_opaque ( opaque_type_key. def_id , opaque_type_key. substs ) ,
251+ hidden_type. ty ,
252+ ty:: error:: TypeError :: Mismatch ,
253+ )
254+ . emit ( ) ;
255+ }
227256 trace ! (
228257 "finalized opaque type {:?} to {:#?}" ,
229258 opaque_type_key,
0 commit comments