fix diagnostics for @ .. binding pattern in tuples and tuple structs

fix comment


add newline for tidy fmt error...


edit suggestion message


change the suggestion message to better handle cases with binding modes


Apply suggestions from estebank code review

Co-authored-by: Esteban Kuber <estebank@users.noreply.github.com>
edits to address source review


Apply suggestions from estebank code review #2

Co-authored-by: Esteban Kuber <estebank@users.noreply.github.com>
update test files
This commit is contained in:
Chris Simpkins 2020-05-29 16:03:46 -04:00
parent 2873165725
commit 27ed143ba9
No known key found for this signature in database
GPG Key ID: 0D0218A71C9DEB09
5 changed files with 76 additions and 3 deletions

View File

@ -3,6 +3,7 @@ use super::{ImplTraitContext, LoweringContext, ParamMode};
use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_span::symbol::Ident;
@ -102,10 +103,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Note that unlike for slice patterns,
// where `xs @ ..` is a legal sub-slice pattern,
// it is not a legal sub-tuple pattern.
if pat.is_rest() {
rest = Some((idx, pat.span));
break;
match pat.kind {
// Found a sub-tuple rest pattern
PatKind::Rest => {
rest = Some((idx, pat.span));
break;
}
// Found a sub-tuple pattern `$binding_mode $ident @ ..`.
// This is not allowed as a sub-tuple pattern
PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => {
rest = Some((idx, pat.span));
let sp = pat.span;
self.diagnostic()
.struct_span_err(
sp,
&format!("`{} @` is not allowed in a {}", ident.name, ctx),
)
.span_label(sp, "this is only allowed in slice patterns")
.help("remove this and bind each tuple field independently")
.span_suggestion_verbose(
sp,
&format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident),
"..".to_string(),
Applicability::MaybeIncorrect,
)
.emit();
break;
}
_ => {}
}
// It was not a sub-tuple pattern so lower it normally.
elems.push(self.lower_pat(pat));
}

View File

@ -0,0 +1,8 @@
fn main() {
let x = (1, 2, 3);
match x {
(_a, _x @ ..) => {}
_ => {}
}
}
//~^^^^ ERROR `_x @` is not allowed in a tuple

View File

@ -0,0 +1,14 @@
error: `_x @` is not allowed in a tuple
--> $DIR/issue-72574-1.rs:4:14
|
LL | (_a, _x @ ..) => {}
| ^^^^^^^ this is only allowed in slice patterns
|
= help: remove this and bind each tuple field independently
help: if you don't need to use the contents of _x, discard the tuple's remaining fields
|
LL | (_a, ..) => {}
| ^^
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
struct Binder(i32, i32, i32);
fn main() {
let x = Binder(1, 2, 3);
match x {
Binder(_a, _x @ ..) => {}
_ => {}
}
}
//~^^^^ ERROR `_x @` is not allowed in a tuple struct

View File

@ -0,0 +1,14 @@
error: `_x @` is not allowed in a tuple struct
--> $DIR/issue-72574-2.rs:6:20
|
LL | Binder(_a, _x @ ..) => {}
| ^^^^^^^ this is only allowed in slice patterns
|
= help: remove this and bind each tuple field independently
help: if you don't need to use the contents of _x, discard the tuple's remaining fields
|
LL | Binder(_a, ..) => {}
| ^^
error: aborting due to previous error