From befdfb5c7113b3d82d973b1acfdcc2b0d9c14ab1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Sep 2021 12:48:58 -0700 Subject: [PATCH] Improve error messages for bad type constraints Co-authored-by: Esteban Kuber --- compiler/rustc_parse/src/parser/path.rs | 31 ++++++++++++------- .../issue-89013-no-assoc.stderr | 6 ++++ .../parser-error-recovery/issue-89013-type.rs | 1 - .../issue-89013-type.stderr | 20 ++---------- .../parser-error-recovery/issue-89013.stderr | 6 ++++ 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 4e4130dfc23..c7d080a80fe 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -495,25 +495,28 @@ impl<'a> Parser<'a> { None => { let after_eq = eq.shrink_to_hi(); let before_next = self.token.span.shrink_to_lo(); - let the_type_placeholder = if matches!(self.token.kind, token::Comma | token::Gt) { - " TheType" - } else { - " TheType " - }; - self.struct_span_err(after_eq.to(before_next), "missing type to the right of `=`") - .span_suggestion( + let mut err = self + .struct_span_err(after_eq.to(before_next), "missing type to the right of `=`"); + if matches!(self.token.kind, token::Comma | token::Gt) { + err.span_suggestion( self.sess.source_map().next_point(eq).to(before_next), "to constrain the associated type, add a type after `=`", - the_type_placeholder.to_string(), + " TheType".to_string(), Applicability::HasPlaceholders, - ) - .span_suggestion( + ); + err.span_suggestion( eq.to(before_next), &format!("remove the `=` if `{}` is a type", ident), String::new(), Applicability::MaybeIncorrect, ) - .emit(); + } else { + err.span_label( + self.token.span, + &format!("expected type, found {}", super::token_descr(&self.token)), + ) + }; + return Err(err); } } Ok(self.mk_ty(span, ast::TyKind::Err)) @@ -584,6 +587,12 @@ impl<'a> Parser<'a> { "expected lifetime, type, or constant, found keyword `const`", ); if self.check_const_arg() { + err.span_suggestion_verbose( + start.until(self.token.span), + "the `const` keyword is only needed in the definition of the type", + String::new(), + Applicability::MaybeIncorrect, + ); err.emit(); GenericArg::Const(self.parse_const_arg()?) } else { diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr index 533d381fa31..ddddd86ab9c 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr @@ -3,6 +3,12 @@ error: expected lifetime, type, or constant, found keyword `const` | LL | impl Foo for Bar { | ^^^^^ + | +help: the `const` keyword is only needed in the definition of the type + | +LL - impl Foo for Bar { +LL + impl Foo<3> for Bar { + | error: aborting due to previous error diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs index c34936d1976..0ec6762b6e2 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs @@ -8,7 +8,6 @@ const T: usize = 42; impl Foo for Bar { //~^ERROR missing type to the right of `=` -//~^^ERROR found keyword `type` fn do_x(&self) -> [u8; 3] { [0u8; 3] } diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr index 0f33f4b0df6..f0d0d90c774 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr @@ -2,23 +2,7 @@ error: missing type to the right of `=` --> $DIR/issue-89013-type.rs:9:13 | LL | impl Foo for Bar { - | ^ - | -help: to constrain the associated type, add a type after `=` - | -LL | impl Foo for Bar { - | +++++++ -help: remove the `=` if `N` is a type - | -LL - impl Foo for Bar { -LL + impl Foo for Bar { - | + | ^---- expected type, found keyword `type` -error: expected one of `,`, `>`, a const expression, lifetime, or type, found keyword `type` - --> $DIR/issue-89013-type.rs:9:14 - | -LL | impl Foo for Bar { - | ^^^^ expected one of `,`, `>`, a const expression, lifetime, or type - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr index 3df459ce162..a60e17aef58 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -3,6 +3,12 @@ error: expected lifetime, type, or constant, found keyword `const` | LL | impl Foo for Bar { | ^^^^^ + | +help: the `const` keyword is only needed in the definition of the type + | +LL - impl Foo for Bar { +LL + impl Foo for Bar { + | error: cannot constrain an associated constant to a value --> $DIR/issue-89013.rs:9:10