about summary refs log tree commit diff
path: root/compiler/rustc_borrowck
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-07-16 20:08:04 +0000
committerMichael Goulet <michael@errs.io>2022-07-19 16:22:33 +0000
commite8d9f38141a0ee8ac5484783e1fb5c218f9d2eee (patch)
treed00ebdfbc1f535346fb1229c80938a5ab1d65efd /compiler/rustc_borrowck
parent8bd12e8cca3f28f302b9cc0f1f47bb64bd1f98fd (diff)
downloadrust-e8d9f38141a0ee8ac5484783e1fb5c218f9d2eee.tar.gz
rust-e8d9f38141a0ee8ac5484783e1fb5c218f9d2eee.zip
Do not allow typeck children items to constrain outer RPITs
Diffstat (limited to 'compiler/rustc_borrowck')
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs29
1 files changed, 29 insertions, 0 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 8e763a02af3..4776c11e309 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -21,6 +21,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
 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;
@@ -224,6 +225,34 @@ pub(crate) fn type_check<'mir, 'tcx>(
                     )
                     .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,