From 7239d7717188f6dc2b380a40335a0c8571be6502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 6 Jul 2017 14:29:55 -0700 Subject: [PATCH] Point at `:` when using it instead of `;` When triggering type ascription in such a way that we can infer a statement end was intended, add a suggestion for the change. Always point out the reason for the expectation of a type is due to type ascription. --- src/libsyntax/parse/parser.rs | 17 +++++++++++++++- ...ype-ascription-instead-of-statement-end.rs | 20 +++++++++++++++++++ ...ascription-instead-of-statement-end.stderr | 16 +++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 74b2ea1df323a..1b6c3cf94e4f4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2798,7 +2798,22 @@ impl<'a> Parser<'a> { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; continue } else if op == AssocOp::Colon { - lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?; + 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.codemap(); + 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, + "did you mean to end the statement here instead?", + ";".to_string()); + } + return Err(err); + } + }; continue } else if op == AssocOp::DotDot || op == AssocOp::DotDotDot { // If we didn’t have to handle `x..`/`x...`, it would be pretty easy to diff --git a/src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs new file mode 100644 index 0000000000000..93de55a39e954 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(type_ascription)] + +fn main() { + println!("test"): + 0; +} + +fn foo() { + println!("test"): 0; +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr new file mode 100644 index 0000000000000..e4cf78dbb2d9f --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-statement-end.stderr @@ -0,0 +1,16 @@ +error: expected type, found `0` + --> $DIR/type-ascription-instead-of-statement-end.rs:15:5 + | +14 | println!("test"): + | - help: did you mean to end the statement here instead? `;` +15 | 0; + | ^ expecting a type here because of type ascription + +error: expected type, found `0` + --> $DIR/type-ascription-instead-of-statement-end.rs:19:23 + | +19 | println!("test"): 0; + | ^ expecting a type here because of type ascription + +error: aborting due to 2 previous errors +