@@ -21,6 +21,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
21
21
use rustc_infer:: infer:: {
22
22
InferCtxt , InferOk , LateBoundRegion , LateBoundRegionConversionTime , NllRegionVariableOrigin ,
23
23
} ;
24
+ use rustc_infer:: traits:: ObligationCause ;
24
25
use rustc_middle:: mir:: tcx:: PlaceTy ;
25
26
use rustc_middle:: mir:: visit:: { NonMutatingUseContext , PlaceContext , Visitor } ;
26
27
use rustc_middle:: mir:: AssertKind ;
@@ -224,6 +225,34 @@ pub(crate) fn type_check<'mir, 'tcx>(
224
225
)
225
226
. unwrap ( ) ;
226
227
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
+ }
227
256
trace ! (
228
257
"finalized opaque type {:?} to {:#?}" ,
229
258
opaque_type_key,
0 commit comments