Skip to content

Commit 27ed143

Browse files
committed
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
1 parent 2873165 commit 27ed143

File tree

5 files changed

+76
-3
lines changed

5 files changed

+76
-3
lines changed

src/librustc_ast_lowering/pat.rs

+30-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::{ImplTraitContext, LoweringContext, ParamMode};
33
use rustc_ast::ast::*;
44
use rustc_ast::ptr::P;
55
use rustc_data_structures::stack::ensure_sufficient_stack;
6+
use rustc_errors::Applicability;
67
use rustc_hir as hir;
78
use rustc_hir::def::Res;
89
use rustc_span::symbol::Ident;
@@ -102,10 +103,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
102103
// Note that unlike for slice patterns,
103104
// where `xs @ ..` is a legal sub-slice pattern,
104105
// it is not a legal sub-tuple pattern.
105-
if pat.is_rest() {
106-
rest = Some((idx, pat.span));
107-
break;
106+
match pat.kind {
107+
// Found a sub-tuple rest pattern
108+
PatKind::Rest => {
109+
rest = Some((idx, pat.span));
110+
break;
111+
}
112+
// Found a sub-tuple pattern `$binding_mode $ident @ ..`.
113+
// This is not allowed as a sub-tuple pattern
114+
PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => {
115+
rest = Some((idx, pat.span));
116+
let sp = pat.span;
117+
self.diagnostic()
118+
.struct_span_err(
119+
sp,
120+
&format!("`{} @` is not allowed in a {}", ident.name, ctx),
121+
)
122+
.span_label(sp, "this is only allowed in slice patterns")
123+
.help("remove this and bind each tuple field independently")
124+
.span_suggestion_verbose(
125+
sp,
126+
&format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident),
127+
"..".to_string(),
128+
Applicability::MaybeIncorrect,
129+
)
130+
.emit();
131+
break;
132+
}
133+
_ => {}
108134
}
135+
109136
// It was not a sub-tuple pattern so lower it normally.
110137
elems.push(self.lower_pat(pat));
111138
}

src/test/ui/issues/issue-72574-1.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let x = (1, 2, 3);
3+
match x {
4+
(_a, _x @ ..) => {}
5+
_ => {}
6+
}
7+
}
8+
//~^^^^ ERROR `_x @` is not allowed in a tuple
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: `_x @` is not allowed in a tuple
2+
--> $DIR/issue-72574-1.rs:4:14
3+
|
4+
LL | (_a, _x @ ..) => {}
5+
| ^^^^^^^ this is only allowed in slice patterns
6+
|
7+
= help: remove this and bind each tuple field independently
8+
help: if you don't need to use the contents of _x, discard the tuple's remaining fields
9+
|
10+
LL | (_a, ..) => {}
11+
| ^^
12+
13+
error: aborting due to previous error
14+

src/test/ui/issues/issue-72574-2.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
struct Binder(i32, i32, i32);
2+
3+
fn main() {
4+
let x = Binder(1, 2, 3);
5+
match x {
6+
Binder(_a, _x @ ..) => {}
7+
_ => {}
8+
}
9+
}
10+
//~^^^^ ERROR `_x @` is not allowed in a tuple struct
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: `_x @` is not allowed in a tuple struct
2+
--> $DIR/issue-72574-2.rs:6:20
3+
|
4+
LL | Binder(_a, _x @ ..) => {}
5+
| ^^^^^^^ this is only allowed in slice patterns
6+
|
7+
= help: remove this and bind each tuple field independently
8+
help: if you don't need to use the contents of _x, discard the tuple's remaining fields
9+
|
10+
LL | Binder(_a, ..) => {}
11+
| ^^
12+
13+
error: aborting due to previous error
14+

0 commit comments

Comments
 (0)