Skip to content

Commit

Permalink
Fix an ICE on an invalid binding @ ... in a tuple struct pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubadamw committed Jul 20, 2020
1 parent d3df851 commit f5e5eb6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1500,11 +1500,17 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
pat_src: PatternSource,
bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
) {
let is_tuple_struct_pat = matches!(pat.kind, PatKind::TupleStruct(_, _));

// Visit all direct subpatterns of this pattern.
pat.walk(&mut |pat| {
debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind);
match pat.kind {
PatKind::Ident(bmode, ident, ref sub) => {
// In tuple struct patterns ignore the invalid `ident @ ...`.
// It will be handled as an error by the AST lowering.
PatKind::Ident(bmode, ident, ref sub)
if !(is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some()) =>
{
// First try to resolve the identifier as some existing entity,
// then fall back to a fresh binding.
let has_sub = sub.is_some();
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/issues/issue-74539.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
enum E {
A(u8, u8),
}

fn main() {
let e = E::A(2, 3);
match e {
E::A(x @ ..) => { //~ ERROR `x @` is not allowed in a tuple
x //~ ERROR cannot find value `x` in this scope
}
};
}
21 changes: 21 additions & 0 deletions src/test/ui/issues/issue-74539.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0425]: cannot find value `x` in this scope
--> $DIR/issue-74539.rs:9:13
|
LL | x
| ^ help: a local variable with a similar name exists: `e`

error: `x @` is not allowed in a tuple struct
--> $DIR/issue-74539.rs:8:14
|
LL | E::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 | E::A(..) => {
| ^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0425`.

0 comments on commit f5e5eb6

Please sign in to comment.