From 8ba1a97e375451f51d0657e2135d4e6e657fd72e Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 12 Mar 2019 19:27:10 -0700 Subject: Expand suggestions for type ascription parse errors --- src/libsyntax/parse/parser.rs | 79 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 13 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5627ac3fcf2..d052abf96d7 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3546,22 +3546,19 @@ impl<'a> Parser<'a> { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; continue } else if op == AssocOp::Colon { + let maybe_path = self.could_ascription_be_path(&lhs.node); + let next_sp = self.span; + lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) { Ok(lhs) => lhs, Err(mut err) => { - err.span_label(self.span, - "expecting a type here because of type ascription"); - let cm = self.sess.source_map(); - let cur_pos = cm.lookup_char_pos(self.span.lo()); - let op_pos = cm.lookup_char_pos(cur_op_span.hi()); - if cur_pos.line != op_pos.line { - err.span_suggestion( - cur_op_span, - "try using a semicolon", - ";".to_string(), - Applicability::MaybeIncorrect // speculative - ); - } + self.bad_type_ascription( + &mut err, + lhs_span, + cur_op_span, + next_sp, + maybe_path, + ); return Err(err); } }; @@ -3666,6 +3663,62 @@ impl<'a> Parser<'a> { Ok(lhs) } + fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool { + self.token.is_ident() && + if let ast::ExprKind::Path(..) = node { true } else { false } && + !self.token.is_reserved_ident() && // v `foo:bar(baz)` + self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) || + self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar, + lhs_span: Span, + cur_op_span: Span, + next_sp: Span, + maybe_path: bool, + ) { + err.span_label(self.span, "expecting a type here because of type ascription"); + let cm = self.sess.source_map(); + let next_pos = cm.lookup_char_pos(next_sp.lo()); + let op_pos = cm.lookup_char_pos(cur_op_span.hi()); + if op_pos.line != next_pos.line { + err.span_suggestion( + cur_op_span, + "try using a semicolon", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + if maybe_path { + err.span_suggestion( + cur_op_span, + "maybe you meant to write a path separator here", + "::".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.note("type ascription is a nightly only feature that lets \ + you annotate expressions with a type: `: `"); + err.span_note( + lhs_span, + "this expression is annotated with type ascription...", + ); + err.span_note( + cur_op_span, + "...due to this, which is why a type is expected after", + ); + err.help("this might be indicative of a syntax error elsewhere"); + } + } + } + fn parse_assoc_op_cast(&mut self, lhs: P, lhs_span: Span, expr_kind: fn(P, P) -> ExprKind) -> PResult<'a, P> { -- cgit 1.4.1-3-g733a5 From 44a086ef39b2a6e6ed231869a5166bec7c4b7511 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 19 Mar 2019 18:16:55 -0700 Subject: Review comment --- src/libsyntax/parse/parser.rs | 4 ++-- src/test/ui/error-codes/E0423.stderr | 4 ++-- src/test/ui/issues/issue-22644.stderr | 2 +- src/test/ui/issues/issue-34255-1.stderr | 2 +- src/test/ui/lifetime_starts_expressions.stderr | 2 +- src/test/ui/parser/struct-literal-in-for.stderr | 2 +- src/test/ui/parser/struct-literal-in-if.stderr | 2 +- src/test/ui/parser/struct-literal-in-while.stderr | 2 +- src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr | 2 +- src/test/ui/type/type-ascription-instead-of-statement-end.stderr | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d052abf96d7..d5b64eaaef5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3704,8 +3704,8 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ); } else { - err.note("type ascription is a nightly only feature that lets \ - you annotate expressions with a type: `: `"); + err.note("type ascription is a nightly-only feature that lets \ + you annotate an expression with a type: `: `"); err.span_note( lhs_span, "this expression is annotated with type ascription...", diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index af5f88f4ce5..29a264ba162 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -4,7 +4,7 @@ error: expected type, found `1` LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/E0423.rs:12:36 | @@ -29,7 +29,7 @@ error: expected type, found `0` LL | for _ in std::ops::Range { start: 0, end: 10 } {} | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/E0423.rs:21:32 | diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 08758ce9c94..5d40909f097 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -89,7 +89,7 @@ error: expected type, found `4` LL | println!("{}", a: &mut 4); | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/issue-22644.rs:34:20 | diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr index ea324302d40..15779705426 100644 --- a/src/test/ui/issues/issue-34255-1.stderr +++ b/src/test/ui/issues/issue-34255-1.stderr @@ -4,7 +4,7 @@ error: expected type, found `42` LL | Test::Drill(field: 42); | ^^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/issue-34255-1.rs:8:17 | diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr index 3de3298e3b5..850e3563cab 100644 --- a/src/test/ui/lifetime_starts_expressions.stderr +++ b/src/test/ui/lifetime_starts_expressions.stderr @@ -14,7 +14,7 @@ error: expected type, found keyword `loop` LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/lifetime_starts_expressions.rs:6:12 | diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr index 2940f465826..9056fac4226 100644 --- a/src/test/ui/parser/struct-literal-in-for.stderr +++ b/src/test/ui/parser/struct-literal-in-for.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-in-for.rs:13:9 | diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr index e7d22ae0292..558f5a15cc5 100644 --- a/src/test/ui/parser/struct-literal-in-if.stderr +++ b/src/test/ui/parser/struct-literal-in-if.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-in-if.rs:13:9 | diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr index 038e30956ff..ae6e1d4577c 100644 --- a/src/test/ui/parser/struct-literal-in-while.stderr +++ b/src/test/ui/parser/struct-literal-in-while.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-in-while.rs:13:9 | diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr index b3a6f6ac734..6dbf7eb1b10 100644 --- a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr +++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-restrictions-in-lamda.rs:13:9 | diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr index 4077be9d082..c80056e4487 100644 --- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -12,7 +12,7 @@ error: expected type, found `0` LL | println!("test"): 0; | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/type-ascription-instead-of-statement-end.rs:9:5 | -- cgit 1.4.1-3-g733a5 From d72ef21ddd4d56b3ec169a5ed64fa4cbf778c5c8 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Fri, 22 Mar 2019 20:14:20 -0700 Subject: Reword type ascription note to reduce verbosity --- src/libsyntax/parse/parser.rs | 6 +----- src/test/ui/error-codes/E0423.stderr | 14 ++------------ src/test/ui/issues/issue-22644.stderr | 7 +------ src/test/ui/issues/issue-34255-1.stderr | 7 +------ src/test/ui/lifetime_starts_expressions.stderr | 7 +------ src/test/ui/parser/struct-literal-in-for.stderr | 7 +------ src/test/ui/parser/struct-literal-in-if.stderr | 7 +------ src/test/ui/parser/struct-literal-in-while.stderr | 7 +------ .../ui/parser/struct-literal-restrictions-in-lamda.stderr | 7 +------ .../type/type-ascription-instead-of-statement-end.stderr | 7 +------ 10 files changed, 11 insertions(+), 65 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d5b64eaaef5..ea81094a996 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3708,11 +3708,7 @@ impl<'a> Parser<'a> { you annotate an expression with a type: `: `"); err.span_note( lhs_span, - "this expression is annotated with type ascription...", - ); - err.span_note( - cur_op_span, - "...due to this, which is why a type is expected after", + "this expression expects an ascribed type after the colon", ); err.help("this might be indicative of a syntax error elsewhere"); } diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index 29a264ba162..b0ef4e1b254 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -5,16 +5,11 @@ LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/E0423.rs:12:36 | LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/E0423.rs:12:37 - | -LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } - | ^ = help: this might be indicative of a syntax error elsewhere error: expected expression, found `==` @@ -30,16 +25,11 @@ LL | for _ in std::ops::Range { start: 0, end: 10 } {} | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/E0423.rs:21:32 | LL | for _ in std::ops::Range { start: 0, end: 10 } {} | ^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/E0423.rs:21:37 - | -LL | for _ in std::ops::Range { start: 0, end: 10 } {} - | ^ = help: this might be indicative of a syntax error elsewhere error[E0423]: expected function, found struct `Foo` diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 5d40909f097..a28ea0d09f8 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -90,16 +90,11 @@ LL | println!("{}", a: &mut 4); | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/issue-22644.rs:34:20 | LL | println!("{}", a: &mut 4); | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/issue-22644.rs:34:21 - | -LL | println!("{}", a: &mut 4); - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to 9 previous errors diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr index 15779705426..7899c8d30f1 100644 --- a/src/test/ui/issues/issue-34255-1.stderr +++ b/src/test/ui/issues/issue-34255-1.stderr @@ -5,16 +5,11 @@ LL | Test::Drill(field: 42); | ^^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/issue-34255-1.rs:8:17 | LL | Test::Drill(field: 42); | ^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/issue-34255-1.rs:8:22 - | -LL | Test::Drill(field: 42); - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to previous error diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr index 850e3563cab..cb5a52a3e08 100644 --- a/src/test/ui/lifetime_starts_expressions.stderr +++ b/src/test/ui/lifetime_starts_expressions.stderr @@ -15,16 +15,11 @@ LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/lifetime_starts_expressions.rs:6:12 | LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^^^^^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/lifetime_starts_expressions.rs:6:24 - | -LL | loop { break 'label: loop { break 'label 42; }; } - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr index 9056fac4226..07f2e41ac4f 100644 --- a/src/test/ui/parser/struct-literal-in-for.stderr +++ b/src/test/ui/parser/struct-literal-in-for.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-in-for.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-in-for.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr index 558f5a15cc5..3dd61e74f12 100644 --- a/src/test/ui/parser/struct-literal-in-if.stderr +++ b/src/test/ui/parser/struct-literal-in-if.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-in-if.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-in-if.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr index ae6e1d4577c..d48244654cd 100644 --- a/src/test/ui/parser/struct-literal-in-while.stderr +++ b/src/test/ui/parser/struct-literal-in-while.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-in-while.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-in-while.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr index 6dbf7eb1b10..a8c93233dbc 100644 --- a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr +++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-restrictions-in-lamda.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-restrictions-in-lamda.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr index c80056e4487..2084cbcce4f 100644 --- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -13,16 +13,11 @@ LL | println!("test"): 0; | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/type-ascription-instead-of-statement-end.rs:9:5 | LL | println!("test"): 0; | ^^^^^^^^^^^^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/type-ascription-instead-of-statement-end.rs:9:21 - | -LL | println!("test"): 0; - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to 2 previous errors -- cgit 1.4.1-3-g733a5