From e89ce461d39686a899cd88e53dc13dcec9445c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 22 Sep 2020 19:25:27 -0700 Subject: [PATCH] Suggest removing bounds even when potential typo --- .../rustc_resolve/src/late/diagnostics.rs | 36 +++++++++++-------- .../traits/trait-bounds-not-on-struct.stderr | 18 +++++++++- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index ca13d749e52..7bd54447c7d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -439,14 +439,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } - if !self.type_ascription_suggestion(&mut err, base_span) - && !self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span) - { - // Fallback label. - err.span_label(base_span, fallback_label); - + if !self.type_ascription_suggestion(&mut err, base_span) { + let mut fallback = false; if let PathSource::Trait(AliasPossibility::Maybe) = source { if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object { + fallback = true; let spans: Vec = bounds .iter() .map(|bound| bound.span()) @@ -500,16 +497,25 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } } - match self.diagnostic_metadata.current_let_binding { - Some((pat_sp, Some(ty_sp), None)) if ty_sp.contains(base_span) && could_be_expr => { - err.span_suggestion_short( - pat_sp.between(ty_sp), - "use `=` if you meant to assign", - " = ".to_string(), - Applicability::MaybeIncorrect, - ); + if !self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span) { + fallback = true; + match self.diagnostic_metadata.current_let_binding { + Some((pat_sp, Some(ty_sp), None)) + if ty_sp.contains(base_span) && could_be_expr => + { + err.span_suggestion_short( + pat_sp.between(ty_sp), + "use `=` if you meant to assign", + " = ".to_string(), + Applicability::MaybeIncorrect, + ); + } + _ => {} } - _ => {} + } + if fallback { + // Fallback label. + err.span_label(base_span, fallback_label); } } (err, candidates) diff --git a/src/test/ui/traits/trait-bounds-not-on-struct.stderr b/src/test/ui/traits/trait-bounds-not-on-struct.stderr index 526dac2db46..0f97e3bdf18 100644 --- a/src/test/ui/traits/trait-bounds-not-on-struct.stderr +++ b/src/test/ui/traits/trait-bounds-not-on-struct.stderr @@ -144,7 +144,23 @@ error[E0404]: expected trait, found struct `Traitor` LL | trait Trait {} | ----------- similarly named trait `Trait` defined here LL | fn g() -> Traitor + 'static { - | ^^^^^^^ help: a trait with a similar name exists: `Trait` + | ^^^^^^^ not a trait + | +help: `+` is used to constrain a "trait object" type with lifetimes or auto-traits; structs and enums can't be bound in that way + --> $DIR/trait-bounds-not-on-struct.rs:35:21 + | +LL | fn g() -> Traitor + 'static { + | ------- ^^^^^^^ ...because of this bound + | | + | expected this type to be a trait... +help: if you meant to use a type and not a trait here, remove the bounds + | +LL | fn g() -> Traitor { + | -- +help: a trait with a similar name exists + | +LL | fn g() -> Trait + 'static { + | ^^^^^ error: aborting due to 11 previous errors