From ca581f91614dacabe1f6629435b9c74720e469cd Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Mon, 5 Jun 2023 15:57:21 +0000
Subject: [PATCH] Don't require associated types with `Self: Sized` bounds in
 `dyn Trait` objects

---
 compiler/rustc_hir_analysis/src/astconv/mod.rs       | 10 ++++++++++
 compiler/rustc_middle/src/query/mod.rs               |  4 ++++
 .../src/traits/object_safety.rs                      |  7 ++++++-
 tests/ui/object-safety/assoc_type_bounds_sized.rs    |  4 +++-
 .../ui/object-safety/assoc_type_bounds_sized.stderr  | 12 ------------
 5 files changed, 23 insertions(+), 14 deletions(-)
 delete mode 100644 tests/ui/object-safety/assoc_type_bounds_sized.stderr

diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 752c5ad535a..6291d124ab4 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1131,6 +1131,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
         }
 
+        for def_ids in associated_types.values_mut() {
+            for def_id in def_ids.clone() {
+                // If the associated type has a `where Self: Sized` bound, we do not need to constrain the associated
+                // type in the `dyn Trait`.
+                if tcx.generics_require_sized_self(def_id) {
+                    def_ids.remove(&def_id);
+                }
+            }
+        }
+
         self.complain_about_missing_associated_types(
             associated_types,
             potential_assoc_types,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 6f942e0bc86..0e1c6d19e31 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2197,6 +2197,10 @@ rustc_queries! {
         desc { "getting cfg-ed out item names" }
         separate_provide_extern
     }
+
+    query generics_require_sized_self(def_id: DefId) -> bool {
+        desc { "check whether the item has a `where Self: Sized` bound" }
+    }
 }
 
 rustc_query_append! { define_callbacks! }
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 08be60c65d4..6a9f0ffc425 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -922,5 +922,10 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
 }
 
 pub fn provide(providers: &mut Providers) {
-    *providers = Providers { object_safety_violations, check_is_object_safe, ..*providers };
+    *providers = Providers {
+        object_safety_violations,
+        check_is_object_safe,
+        generics_require_sized_self,
+        ..*providers
+    };
 }
diff --git a/tests/ui/object-safety/assoc_type_bounds_sized.rs b/tests/ui/object-safety/assoc_type_bounds_sized.rs
index 61ad3cf9dc6..546cde37f63 100644
--- a/tests/ui/object-safety/assoc_type_bounds_sized.rs
+++ b/tests/ui/object-safety/assoc_type_bounds_sized.rs
@@ -1,9 +1,11 @@
+// check-pass
+
 trait Foo {
     type Bar
     where
         Self: Sized;
 }
 
-fn foo(_: &dyn Foo) {} //~ ERROR: the value of the associated type `Bar` (from trait `Foo`) must be specified
+fn foo(_: &dyn Foo) {}
 
 fn main() {}
diff --git a/tests/ui/object-safety/assoc_type_bounds_sized.stderr b/tests/ui/object-safety/assoc_type_bounds_sized.stderr
deleted file mode 100644
index 49d624f9b1d..00000000000
--- a/tests/ui/object-safety/assoc_type_bounds_sized.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified
-  --> $DIR/assoc_type_bounds_sized.rs:7:16
-   |
-LL |     type Bar
-   |     -------- `Bar` defined here
-...
-LL | fn foo(_: &dyn Foo) {}
-   |                ^^^ help: specify the associated type: `Foo<Bar = Type>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0191`.