about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-03-23 00:00:34 +0530
committerGitHub <noreply@github.com>2023-03-23 00:00:34 +0530
commitb9151b2d7014149be2acdea29ae9fa272dd11583 (patch)
treeb86785363525b10cad32a5251a7efa1edcd6e8ec
parent8ce52b7b65927c83189175e2488a3047201a5e8c (diff)
parentc3e6f689312872ac9859b18230c6323ab27fbd7f (diff)
downloadrust-b9151b2d7014149be2acdea29ae9fa272dd11583.tar.gz
rust-b9151b2d7014149be2acdea29ae9fa272dd11583.zip
Rollup merge of #109405 - compiler-errors:rpitit-as-opaques, r=spastorino
RPITITs are `DefKind::Opaque` with new lowering strategy

r? `@spastorino`

Kinda cherry-picked #109400
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs12
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs21
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs24
-rw-r--r--tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs2
5 files changed, 45 insertions, 16 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 4082759006d..d8dda7a93be 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -305,7 +305,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
     }) = item.kind
     {
         let substs = InternalSubsts::identity_for_item(tcx, def_id);
-        let opaque_identity_ty = if in_trait {
+        let opaque_identity_ty = if in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
             tcx.mk_projection(def_id.to_def_id(), substs)
         } else {
             tcx.mk_opaque(def_id.to_def_id(), substs)
@@ -554,7 +554,15 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
             check_union(tcx, id.owner_id.def_id);
         }
         DefKind::OpaqueTy => {
-            check_opaque(tcx, id);
+            let opaque = tcx.hir().expect_item(id.owner_id.def_id).expect_opaque_ty();
+            if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = opaque.origin
+                && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
+                && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
+            {
+                // Skip opaques from RPIT in traits with no default body.
+            } else {
+                check_opaque(tcx, id);
+            }
         }
         DefKind::ImplTraitPlaceholder => {
             let parent = tcx.impl_trait_in_trait_parent_fn(id.owner_id.to_def_id());
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index ef3eda584e1..4dd433a50a7 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1016,7 +1016,6 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         | DefKind::Const
         | DefKind::Static(..)
         | DefKind::TyAlias
-        | DefKind::OpaqueTy
         | DefKind::ForeignTy
         | DefKind::Impl { .. }
         | DefKind::AssocFn
@@ -1027,6 +1026,18 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         | DefKind::AnonConst
         | DefKind::InlineConst => true,
 
+        DefKind::OpaqueTy => {
+            let opaque = tcx.hir().expect_item(def_id).expect_opaque_ty();
+            if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = opaque.origin
+                && let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
+                && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
+            {
+                false
+            } else {
+                true
+            }
+        }
+
         DefKind::ImplTraitPlaceholder => {
             let parent_def_id = tcx.impl_trait_in_trait_parent_fn(def_id.to_def_id());
             let assoc_item = tcx.associated_item(parent_def_id);
@@ -1044,7 +1055,13 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
             let assoc_item = tcx.associated_item(def_id);
             match assoc_item.container {
                 ty::AssocItemContainer::ImplContainer => true,
-                ty::AssocItemContainer::TraitContainer => assoc_item.defaultness(tcx).has_value(),
+                // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) always encode RPITITs,
+                // since we need to be able to "project" from an RPITIT associated item
+                // to an opaque when installing the default projection predicates in
+                // default trait methods with RPITITs.
+                ty::AssocItemContainer::TraitContainer => {
+                    assoc_item.defaultness(tcx).has_value() || assoc_item.opt_rpitit_info.is_some()
+                }
             }
         }
         DefKind::TyParam => {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index b2bae47054c..89a485b47ca 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -188,7 +188,7 @@ impl<'hir> Map<'hir> {
                 ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
                 ItemKind::Mod(..) => DefKind::Mod,
                 ItemKind::OpaqueTy(ref opaque) => {
-                    if opaque.in_trait {
+                    if opaque.in_trait && !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
                         DefKind::ImplTraitPlaceholder
                     } else {
                         DefKind::OpaqueTy
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 6d9ad96fa74..562f5bffba3 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -254,13 +254,16 @@ fn associated_type_for_impl_trait_in_trait(
     tcx: TyCtxt<'_>,
     opaque_ty_def_id: LocalDefId,
 ) -> LocalDefId {
-    let fn_def_id = tcx.impl_trait_in_trait_parent_fn(opaque_ty_def_id.to_def_id());
-    let trait_def_id = tcx.parent(fn_def_id);
+    let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) =
+        tcx.hir().expect_item(opaque_ty_def_id).expect_opaque_ty().origin
+    else {
+        bug!("expected opaque for {opaque_ty_def_id:?}");
+    };
+    let trait_def_id = tcx.local_parent(fn_def_id);
     assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);
 
     let span = tcx.def_span(opaque_ty_def_id);
-    let trait_assoc_ty =
-        tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
+    let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, DefPathData::ImplTraitAssocTy);
 
     let local_def_id = trait_assoc_ty.def_id();
     let def_id = local_def_id.to_def_id();
@@ -282,7 +285,7 @@ fn associated_type_for_impl_trait_in_trait(
         container: ty::TraitContainer,
         fn_has_self_parameter: false,
         opt_rpitit_info: Some(ImplTraitInTraitData::Trait {
-            fn_def_id,
+            fn_def_id: fn_def_id.to_def_id(),
             opaque_def_id: opaque_ty_def_id.to_def_id(),
         }),
     });
@@ -324,7 +327,7 @@ fn associated_type_for_impl_trait_in_trait(
             params.iter().map(|param| (param.def_id, param.index)).collect();
 
         ty::Generics {
-            parent: Some(trait_def_id),
+            parent: Some(trait_def_id.to_def_id()),
             parent_count,
             params,
             param_def_id_to_index,
@@ -335,7 +338,7 @@ fn associated_type_for_impl_trait_in_trait(
 
     // There are no predicates for the synthesized associated type.
     trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
-        parent: Some(trait_def_id),
+        parent: Some(trait_def_id.to_def_id()),
         predicates: &[],
     });
 
@@ -356,7 +359,6 @@ fn associated_type_for_impl_trait_in_impl(
     impl_fn_def_id: LocalDefId,
 ) -> LocalDefId {
     let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
-    let impl_def_id = impl_local_def_id.to_def_id();
 
     // FIXME fix the span, we probably want the def_id of the return type of the function
     let span = tcx.def_span(impl_fn_def_id);
@@ -402,7 +404,7 @@ fn associated_type_for_impl_trait_in_impl(
         let trait_assoc_parent_count = trait_assoc_generics.parent_count;
         let mut params = trait_assoc_generics.params.clone();
 
-        let parent_generics = tcx.generics_of(impl_def_id);
+        let parent_generics = tcx.generics_of(impl_local_def_id.to_def_id());
         let parent_count = parent_generics.parent_count + parent_generics.params.len();
 
         for param in &mut params {
@@ -413,7 +415,7 @@ fn associated_type_for_impl_trait_in_impl(
             params.iter().map(|param| (param.def_id, param.index)).collect();
 
         ty::Generics {
-            parent: Some(impl_def_id),
+            parent: Some(impl_local_def_id.to_def_id()),
             parent_count,
             params,
             param_def_id_to_index,
@@ -424,7 +426,7 @@ fn associated_type_for_impl_trait_in_impl(
 
     // There are no predicates for the synthesized associated type.
     impl_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
-        parent: Some(impl_def_id),
+        parent: Some(impl_local_def_id.to_def_id()),
         predicates: &[],
     });
 
diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
index 74df300f85a..74f7bc603aa 100644
--- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
@@ -1,3 +1,5 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+
 #![feature(return_position_impl_trait_in_trait)]
 
 pub trait Foo {