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`.