about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-05-05 19:44:10 +0000
committerPietro Albini <pietro@pietroalbini.org>2025-05-09 18:12:08 +0200
commit2f71d0a243f31f346f868808f8ff5892a8ff8279 (patch)
tree963abfdda44e76e2ca500f228345d81a4915d9cf
parentfd5b1583fe3c7e2a866b18a42e9dcde0c647802d (diff)
downloadrust-2f71d0a243f31f346f868808f8ff5892a8ff8279.tar.gz
rust-2f71d0a243f31f346f868808f8ff5892a8ff8279.zip
Only include associated type bounds for Self:Sized associated types if they are provided
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs9
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs5
-rw-r--r--tests/ui/traits/object/constrain-via-unnecessary-bound.rs24
-rw-r--r--tests/ui/traits/object/constrain-via-unnecessary-bound.stderr19
-rw-r--r--tests/ui/traits/object/pretty.stderr6
5 files changed, 55 insertions, 8 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 27643e715e6..19f80751d05 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -178,9 +178,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                 .filter(|item| item.kind == ty::AssocKind::Type)
                                 // No RPITITs -- they're not dyn-compatible for now.
                                 .filter(|item| !item.is_impl_trait_in_trait())
-                                // If the associated type has a `where Self: Sized` bound,
-                                // we do not need to constrain the associated type.
-                                .filter(|item| !tcx.generics_require_sized_self(item.def_id))
                                 .map(|item| (item.def_id, trait_ref)),
                         );
                     }
@@ -259,7 +256,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 if let Some(assoc) = projection_bounds.get(&key) {
                     Some(*assoc)
                 } else {
-                    missing_assoc_types.insert(key);
+                    // If the associated type has a `where Self: Sized` bound,
+                    // we do not need to constrain the associated type.
+                    if !tcx.generics_require_sized_self(key.0) {
+                        missing_assoc_types.insert(key);
+                    }
                     None
                 }
             })
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 74a94d82784..c7193c6f6df 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -720,7 +720,10 @@ impl<'tcx> Ty<'tcx> {
         repr: DynKind,
     ) -> Ty<'tcx> {
         if cfg!(debug_assertions) {
-            let projection_count = obj.projection_bounds().count();
+            let projection_count = obj
+                .projection_bounds()
+                .filter(|item| !tcx.generics_require_sized_self(item.item_def_id()))
+                .count();
             let expected_count: usize = obj
                 .principal_def_id()
                 .into_iter()
diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.rs b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs
new file mode 100644
index 00000000000..5534471fb27
--- /dev/null
+++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/rust/issues/140645>.
+// Test that we lower impossible-to-satisfy associated type bounds, which
+// may for example constrain impl parameters.
+
+pub trait Other {}
+
+pub trait Trait {
+    type Assoc
+    where
+        Self: Sized;
+}
+
+impl Other for dyn Trait {}
+// `dyn Trait<Assoc = ()>` is a different "nominal type" than `dyn Traiat`.
+impl Other for dyn Trait<Assoc = ()> {}
+//~^ WARN unnecessary associated type bound for dyn-incompatible associated type
+
+// I hope it's clear that `dyn Trait` (w/o `Assoc`) wouldn't match this impl.
+impl<T> dyn Trait<Assoc = T> {}
+//~^ WARN unnecessary associated type bound for dyn-incompatible associated type
+
+fn main() {}
diff --git a/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr
new file mode 100644
index 00000000000..4383ca869ea
--- /dev/null
+++ b/tests/ui/traits/object/constrain-via-unnecessary-bound.stderr
@@ -0,0 +1,19 @@
+warning: unnecessary associated type bound for dyn-incompatible associated type
+  --> $DIR/constrain-via-unnecessary-bound.rs:17:26
+   |
+LL | impl Other for dyn Trait<Assoc = ()> {}
+   |                          ^^^^^^^^^^ help: remove this bound
+   |
+   = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
+   = note: `#[warn(unused_associated_type_bounds)]` on by default
+
+warning: unnecessary associated type bound for dyn-incompatible associated type
+  --> $DIR/constrain-via-unnecessary-bound.rs:21:19
+   |
+LL | impl<T> dyn Trait<Assoc = T> {}
+   |                   ^^^^^^^^^ help: remove this bound
+   |
+   = note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr
index 37fe142951d..2f9fdf151f0 100644
--- a/tests/ui/traits/object/pretty.stderr
+++ b/tests/ui/traits/object/pretty.stderr
@@ -154,12 +154,12 @@ error[E0308]: mismatched types
   --> $DIR/pretty.rs:41:56
    |
 LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
-   |                                                     -  ^ expected `()`, found `&dyn HasGat<u8>`
+   |                                                     -  ^ expected `()`, found `&dyn HasGat<u8, Assoc<bool> = ()>`
    |                                                     |
-   |                                                     help: try adding a return type: `-> &dyn HasGat<u8>`
+   |                                                     help: try adding a return type: `-> &dyn HasGat<u8, Assoc<bool> = ()>`
    |
    = note: expected unit type `()`
-              found reference `&dyn HasGat<u8>`
+              found reference `&dyn HasGat<u8, Assoc<bool> = ()>`
 
 error: aborting due to 14 previous errors; 1 warning emitted