Skip to content

Commit

Permalink
fix diagnostics for @ .. binding pattern in tuples and tuple structs
Browse files Browse the repository at this point in the history
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
  • Loading branch information
chrissimpkins committed May 29, 2020
1 parent 2873165 commit 27ed143
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 3 deletions.
33 changes: 30 additions & 3 deletions src/librustc_ast_lowering/pat.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
}
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/issues/issue-72574-1.rs
@@ -0,0 +1,8 @@
fn main() {
let x = (1, 2, 3);
match x {
(_a, _x @ ..) => {}
_ => {}
}
}
//~^^^^ ERROR `_x @` is not allowed in a tuple
14 changes: 14 additions & 0 deletions src/test/ui/issues/issue-72574-1.stderr
@@ -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

10 changes: 10 additions & 0 deletions src/test/ui/issues/issue-72574-2.rs
@@ -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
14 changes: 14 additions & 0 deletions src/test/ui/issues/issue-72574-2.stderr
@@ -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

0 comments on commit 27ed143

Please sign in to comment.