From dda30f690206870ed6f8fc14216e92cdc1f2687a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 26 Jul 2017 18:59:07 +0300 Subject: [PATCH] Better diagnostics and recovery for `mut ref` in patterns --- src/libsyntax/parse/parser.rs | 14 ++++++++++++-- src/test/ui/mut-ref.rs | 16 ++++++++++++++++ src/test/ui/mut-ref.stderr | 8 ++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/mut-ref.rs create mode 100644 src/test/ui/mut-ref.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d6a57c2874f..a48d2dcf1c1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3523,8 +3523,18 @@ impl<'a> Parser<'a> { } // At this point, token != _, &, &&, (, [ _ => if self.eat_keyword(keywords::Mut) { - // Parse mut ident @ pat - pat = self.parse_pat_ident(BindingMode::ByValue(Mutability::Mutable))?; + // Parse mut ident @ pat / mut ref ident @ pat + let mutref_span = self.prev_span.to(self.span); + let binding_mode = if self.eat_keyword(keywords::Ref) { + self.diagnostic() + .struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect") + .span_suggestion(mutref_span, "try switching the order", "ref mut".into()) + .emit(); + BindingMode::ByRef(Mutability::Mutable) + } else { + BindingMode::ByValue(Mutability::Mutable) + }; + pat = self.parse_pat_ident(binding_mode)?; } else if self.eat_keyword(keywords::Ref) { // Parse ref ident @ pat / ref mut ident @ pat let mutbl = self.parse_mutability(); diff --git a/src/test/ui/mut-ref.rs b/src/test/ui/mut-ref.rs new file mode 100644 index 00000000000..f8883699688 --- /dev/null +++ b/src/test/ui/mut-ref.rs @@ -0,0 +1,16 @@ +// 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. + +// compile-flags: -Z parse-only + +fn main() { + let mut ref x = 10; + let ref mut y = 11; +} diff --git a/src/test/ui/mut-ref.stderr b/src/test/ui/mut-ref.stderr new file mode 100644 index 00000000000..ce6a42f1e5e --- /dev/null +++ b/src/test/ui/mut-ref.stderr @@ -0,0 +1,8 @@ +error: the order of `mut` and `ref` is incorrect + --> $DIR/mut-ref.rs:14:9 + | +14 | let mut ref x = 10; + | ^^^^^^^ help: try switching the order: `ref mut` + +error: aborting due to previous error +