From 4d2b607aa8a3ce780c6e14d919ed8b14ce3b5db3 Mon Sep 17 00:00:00 2001
From: Qai Juang <237468078+qaijuang@users.noreply.github.com>
Date: Thu, 23 Apr 2026 12:32:33 +0000
Subject: [PATCH] Fix E0191 suggestion for empty dyn trait args
* Fix E0191 suggestion for empty dyn trait args
* Fix tidy check
* address code nit
* fold test into existing E0191 test
---
.../src/hir_ty_lowering/errors.rs | 12 ++++++------
...t-as-dyn-trait-wo-assoc-type-issue-21950.rs | 15 +++++++++++++++
...-dyn-trait-wo-assoc-type-issue-21950.stderr | 18 ++++++++++++++++--
3 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 784deffce434..0aa478f99200 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -1115,12 +1115,12 @@ enum Descr {
)
})
.collect();
- // FIXME(fmease): Does not account for `dyn Trait<>` (suggs `dyn Trait<, X = Y>`).
- let code = if let Some(snippet) = snippet.strip_suffix('>') {
- // The user wrote `Trait<'a>` or similar and we don't have a term we can suggest,
- // but at least we can clue them to the correct syntax `Trait<'a, Item = /* ... */>`
- // while accounting for the `<'a>` in the suggestion.
- format!("{}, {}>", snippet, bindings.join(", "))
+ let code = if let Some(snippet) = snippet.strip_suffix("<>") {
+ // Empty generics
+ format!("{snippet}<{}>", bindings.join(", "))
+ } else if let Some(snippet) = snippet.strip_suffix('>') {
+ // Non-empty generics
+ format!("{snippet}, {}>", bindings.join(", "))
} else if in_expr_or_pat {
// The user wrote `Trait`, so we don't have a term we can suggest, but at least we
// can clue them to the correct syntax `Trait:: `.
diff --git a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs
index 3c3815054502..f677a7fceeea 100644
--- a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs
+++ b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs
@@ -12,8 +12,23 @@ impl Add for i32 {
type Output = i32;
}
+trait Meow {
+ type Assoc;
+}
+
+struct Cat;
+
+impl Meow for Cat {
+ type Assoc = i32;
+}
+
fn main() {
let x = &10 as &dyn Add; //OK
let x = &10 as &dyn Add;
//~^ ERROR E0191
+
+ // Regression test for https://github.com/rust-lang/rust/issues/155578.
+ let cat = Cat;
+ let _: &dyn Meow<> = &cat;
+ //~^ ERROR E0191
}
diff --git a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr
index 1d9d46489ae1..831dc5431a4d 100644
--- a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr
+++ b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr
@@ -1,5 +1,5 @@
error[E0191]: the value of the associated type `Output` in `Add` must be specified
- --> $DIR/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs:17:25
+ --> $DIR/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs:27:25
|
LL | type Output;
| ----------- `Output` defined here
@@ -12,6 +12,20 @@ help: specify the associated type
LL | let x = &10 as &dyn Add;
| +++++++++++++++++++++
-error: aborting due to 1 previous error
+error[E0191]: the value of the associated type `Assoc` in `Meow` must be specified
+ --> $DIR/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs:32:17
+ |
+LL | type Assoc;
+ | ---------- `Assoc` defined here
+...
+LL | let _: &dyn Meow<> = &cat;
+ | ^^^^^^
+ |
+help: specify the associated type
+ |
+LL | let _: &dyn Meow = &cat;
+ | ++++++++++++++++++
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0191`.