Skip to content

Commit

Permalink
Fix ICEs with @ .. binding
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnTitor committed Jul 30, 2020
1 parent 8b778a5 commit c2afce4
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 7 deletions.
2 changes: 0 additions & 2 deletions src/librustc_ast_lowering/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// 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(
Expand All @@ -128,7 +127,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
Applicability::MaybeIncorrect,
)
.emit();
break;
}
_ => {}
}
Expand Down
4 changes: 1 addition & 3 deletions src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1520,9 +1520,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let has_sub = sub.is_some();
let res = self
.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
.unwrap_or_else(|| {
self.fresh_binding(ident, pat.id, pat_src, bindings)
});
.unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings));
self.r.record_partial_res(pat.id, PartialRes::new(res));
}
PatKind::TupleStruct(ref path, ..) => {
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-72574-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ fn main() {
}
}
//~^^^^ ERROR `_x @` is not allowed in a tuple
//~| ERROR: `..` patterns are not allowed here
//~| ERROR: mismatched types
22 changes: 21 additions & 1 deletion src/test/ui/issues/issue-72574-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,25 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining
LL | (_a, ..) => {}
| ^^

error: aborting due to previous error
error: `..` patterns are not allowed here
--> $DIR/issue-72574-1.rs:4:19
|
LL | (_a, _x @ ..) => {}
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns

error[E0308]: mismatched types
--> $DIR/issue-72574-1.rs:4:9
|
LL | match x {
| - this expression has type `({integer}, {integer}, {integer})`
LL | (_a, _x @ ..) => {}
| ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
|
= note: expected tuple `({integer}, {integer}, {integer})`
found tuple `(_, _)`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-72574-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ fn main() {
}
}
//~^^^^ ERROR `_x @` is not allowed in a tuple struct
//~| ERROR: `..` patterns are not allowed here
//~| ERROR: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
20 changes: 19 additions & 1 deletion src/test/ui/issues/issue-72574-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,23 @@ help: if you don't need to use the contents of _x, discard the tuple's remaining
LL | Binder(_a, ..) => {}
| ^^

error: aborting due to previous error
error: `..` patterns are not allowed here
--> $DIR/issue-72574-2.rs:6:25
|
LL | Binder(_a, _x @ ..) => {}
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns

error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
--> $DIR/issue-72574-2.rs:6:9
|
LL | struct Binder(i32, i32, i32);
| ----------------------------- tuple struct defined here
...
LL | Binder(_a, _x @ ..) => {}
| ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0023`.
15 changes: 15 additions & 0 deletions src/test/ui/pattern/issue-74539.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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 struct
//~| ERROR: `..` patterns are not allowed here
//~| ERROR: this pattern has 1 field, but the corresponding tuple variant has 2 fields
x
}
};
}
32 changes: 32 additions & 0 deletions src/test/ui/pattern/issue-74539.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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: `..` patterns are not allowed here
--> $DIR/issue-74539.rs:8:18
|
LL | E::A(x @ ..) => {
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns

error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
--> $DIR/issue-74539.rs:8:9
|
LL | A(u8, u8),
| --------- tuple variant defined here
...
LL | E::A(x @ ..) => {
| ^^^^^^^^^^^^ expected 2 fields, found 1

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0023`.
7 changes: 7 additions & 0 deletions src/test/ui/pattern/issue-74702.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
let (foo @ ..,) = (0, 0);
//~^ ERROR: `foo @` is not allowed in a tuple
//~| ERROR: `..` patterns are not allowed here
//~| ERROR: mismatched types
dbg!(foo);
}
34 changes: 34 additions & 0 deletions src/test/ui/pattern/issue-74702.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
error: `foo @` is not allowed in a tuple
--> $DIR/issue-74702.rs:2:10
|
LL | let (foo @ ..,) = (0, 0);
| ^^^^^^^^ 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 foo, discard the tuple's remaining fields
|
LL | let (..,) = (0, 0);
| ^^

error: `..` patterns are not allowed here
--> $DIR/issue-74702.rs:2:16
|
LL | let (foo @ ..,) = (0, 0);
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns

error[E0308]: mismatched types
--> $DIR/issue-74702.rs:2:9
|
LL | let (foo @ ..,) = (0, 0);
| ^^^^^^^^^^^ ------ this expression has type `({integer}, {integer})`
| |
| expected a tuple with 2 elements, found one with 1 element
|
= note: expected tuple `({integer}, {integer})`
found tuple `(_,)`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
7 changes: 7 additions & 0 deletions src/test/ui/pattern/issue-74954.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// check-pass

fn main() {
if let Some([b'@', filename @ ..]) = Some(b"@abc123") {
println!("filename {:?}", filename);
}
}

0 comments on commit c2afce4

Please sign in to comment.