summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_parse/src/parser/stmt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src/parser/stmt.rs')
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs59
1 files changed, 45 insertions, 14 deletions
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index aa939a71d..1ee5a96d5 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -53,7 +53,7 @@ impl<'a> Parser<'a> {
// Don't use `maybe_whole` so that we have precise control
// over when we bump the parser
if let token::Interpolated(nt) = &self.token.kind
- && let token::NtStmt(stmt) = &**nt
+ && let token::NtStmt(stmt) = &nt.0
{
let mut stmt = stmt.clone();
self.bump();
@@ -384,10 +384,10 @@ impl<'a> Parser<'a> {
fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
if let ast::ExprKind::Binary(op, ..) = init.kind {
- if op.node.lazy() {
+ if op.node.is_lazy() {
self.sess.emit_err(errors::InvalidExpressionInLetElse {
span: init.span,
- operator: op.node.to_string(),
+ operator: op.node.as_str(),
sugg: errors::WrapExpressionInParentheses {
left: init.span.shrink_to_lo(),
right: init.span.shrink_to_hi(),
@@ -567,20 +567,37 @@ impl<'a> Parser<'a> {
snapshot.recover_diff_marker();
}
if self.token == token::Colon {
- // if next token is following a colon, it's likely a path
- // and we can suggest a path separator
- self.bump();
- if self.token.span.lo() == self.prev_token.span.hi() {
+ // if a previous and next token of the current one is
+ // integer literal (e.g. `1:42`), it's likely a range
+ // expression for Pythonistas and we can suggest so.
+ if self.prev_token.is_integer_lit()
+ && self.may_recover()
+ && self.look_ahead(1, |token| token.is_integer_lit())
+ {
+ // FIXME(hkmatsumoto): Might be better to trigger
+ // this only when parsing an index expression.
err.span_suggestion_verbose(
- self.prev_token.span,
- "maybe write a path separator here",
- "::",
+ self.token.span,
+ "you might have meant a range expression",
+ "..",
Applicability::MaybeIncorrect,
);
- }
- if self.sess.unstable_features.is_nightly_build() {
- // FIXME(Nilstrieb): Remove this again after a few months.
- err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
+ } else {
+ // if next token is following a colon, it's likely a path
+ // and we can suggest a path separator
+ self.bump();
+ if self.token.span.lo() == self.prev_token.span.hi() {
+ err.span_suggestion_verbose(
+ self.prev_token.span,
+ "maybe write a path separator here",
+ "::",
+ Applicability::MaybeIncorrect,
+ );
+ }
+ if self.sess.unstable_features.is_nightly_build() {
+ // FIXME(Nilstrieb): Remove this again after a few months.
+ err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
+ }
}
}
@@ -619,6 +636,20 @@ impl<'a> Parser<'a> {
match &mut stmt.kind {
// Expression without semicolon.
StmtKind::Expr(expr)
+ if classify::expr_requires_semi_to_be_stmt(expr)
+ && !expr.attrs.is_empty()
+ && ![token::Eof, token::Semi, token::CloseDelim(Delimiter::Brace)]
+ .contains(&self.token.kind) =>
+ {
+ // The user has written `#[attr] expr` which is unsupported. (#106020)
+ self.attr_on_non_tail_expr(&expr);
+ // We already emitted an error, so don't emit another type error
+ let sp = expr.span.to(self.prev_token.span);
+ *expr = self.mk_expr_err(sp);
+ }
+
+ // Expression without semicolon.
+ StmtKind::Expr(expr)
if self.token != token::Eof && classify::expr_requires_semi_to_be_stmt(expr) =>
{
// Just check for errors and recover; do not eat semicolon yet.