about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-11 13:49:52 +0000
committerbors <bors@rust-lang.org>2022-09-11 13:49:52 +0000
commit17a627fe876ded260d5563751d8d1530275e1c55 (patch)
tree4090e2f9531926312f3b48e3098e989dd20610ff
parent6f0c4a6c5c36f1f8f433a12e10a29918f3d40a31 (diff)
parent1335da9d485879a99c3ba24827781c6ee6705cc6 (diff)
downloadrust-17a627fe876ded260d5563751d8d1530275e1c55.tar.gz
rust-17a627fe876ded260d5563751d8d1530275e1c55.zip
Auto merge of #101682 - compiler-errors:rpitit-encode, r=fee1-dead
Only encode return-position `impl Trait` in trait when parent function has a default body

Semi-blocked on #101679, because I can't currently write a test for when we _should_ encode the type of the return-position `impl Trait` in trait, which is when a trait has a default function body, like so:

```rust
trait Foo {
  fn bar() -> impl Sized { }
}
```

Though this can land even without #101679, since it does prevent ICEs from occuring any time you use `#![feature(return_position_impl_trait_in_trait)]` in a library, which is kind annoying.
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs14
-rw-r--r--src/test/ui/impl-trait/in-trait/encode.rs9
2 files changed, 22 insertions, 1 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index f967ac9a4dc..5a60ea794ed 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1036,7 +1036,6 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         | DefKind::Static(..)
         | DefKind::TyAlias
         | DefKind::OpaqueTy
-        | DefKind::ImplTraitPlaceholder
         | DefKind::ForeignTy
         | DefKind::Impl
         | DefKind::AssocFn
@@ -1047,6 +1046,19 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         | DefKind::AnonConst
         | DefKind::InlineConst => true,
 
+        DefKind::ImplTraitPlaceholder => {
+            let parent_def_id = tcx.impl_trait_in_trait_parent(def_id.to_def_id());
+            let assoc_item = tcx.associated_item(parent_def_id);
+            match assoc_item.container {
+                // Always encode an RPIT in an impl fn, since it always has a body
+                ty::AssocItemContainer::ImplContainer => true,
+                ty::AssocItemContainer::TraitContainer => {
+                    // Encode an RPIT for a trait only if the trait has a default body
+                    assoc_item.defaultness(tcx).has_value()
+                }
+            }
+        }
+
         DefKind::AssocTy => {
             let assoc_item = tcx.associated_item(def_id);
             match assoc_item.container {
diff --git a/src/test/ui/impl-trait/in-trait/encode.rs b/src/test/ui/impl-trait/in-trait/encode.rs
new file mode 100644
index 00000000000..efb9f6498ba
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/encode.rs
@@ -0,0 +1,9 @@
+// build-pass
+// compile-flags: --crate-type=lib
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+    fn bar() -> impl Sized;
+}