about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-08-31 05:12:40 +0000
committerMichael Goulet <michael@errs.io>2022-09-09 01:31:45 +0000
commite8fa74ae45024d1120a73c15a3c21f675b25f1f4 (patch)
treecfb11ecd598bcdcc739b52710de455839f144fc9
parenta4d1807d6d19a446f2f620773d42b5de2dbed757 (diff)
downloadrust-e8fa74ae45024d1120a73c15a3c21f675b25f1f4.tar.gz
rust-e8fa74ae45024d1120a73c15a3c21f675b25f1f4.zip
Check that impl types actually satisfy RPITIT bounds
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index b6bc244d2b1..e55f43994b9 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -391,6 +391,30 @@ fn compare_predicate_entailment<'tcx>(
             return Err(diag.emit());
         }
 
+        // Check that an impl's fn return satisfies the bounds of the
+        // FIXME(RPITIT): Generalize this to nested impl traits
+        if let ty::Projection(proj) = tcx.fn_sig(trait_m.def_id).skip_binder().output().kind()
+            && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
+        {
+            let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
+
+            for (predicate, span) in tcx
+                .bound_explicit_item_bounds(proj.item_def_id)
+                .transpose_iter()
+                .map(|pred| pred.map_bound(|pred| *pred).subst(tcx, trait_to_placeholder_substs))
+            {
+                ocx.register_obligation(traits::Obligation::new(
+                    traits::ObligationCause::new(
+                        return_span,
+                        impl_m_hir_id,
+                        ObligationCauseCode::BindingObligation(proj.item_def_id, span),
+                    ),
+                    param_env,
+                    predicate,
+                ));
+            }
+        }
+
         // Check that all obligations are satisfied by the implementation's
         // version.
         let errors = ocx.select_all_or_error();