fix extra subslice lowering
This commit is contained in:
parent
2e6eaceede
commit
f5bd9646be
@ -128,6 +128,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let mut slice = None;
|
||||
let mut prev_rest_span = None;
|
||||
|
||||
// Lowers `$bm $ident @ ..` to `$bm $ident @ _`.
|
||||
let lower_rest_sub = |this: &mut Self, pat, bm, ident, sub| {
|
||||
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
|
||||
let node = this.lower_pat_ident(pat, bm, ident, lower_sub);
|
||||
this.pat_with_node_id_of(pat, node)
|
||||
};
|
||||
|
||||
let mut iter = pats.iter();
|
||||
// Lower all the patterns until the first occurrence of a sub-slice pattern.
|
||||
for pat in iter.by_ref() {
|
||||
@ -142,9 +149,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
|
||||
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
|
||||
prev_rest_span = Some(sub.span);
|
||||
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
|
||||
let node = self.lower_pat_ident(pat, bm, ident, lower_sub);
|
||||
slice = Some(self.pat_with_node_id_of(pat, node));
|
||||
slice = Some(lower_rest_sub(self, pat, bm, ident, sub));
|
||||
break;
|
||||
}
|
||||
// It was not a subslice pattern so lower it normally.
|
||||
@ -157,9 +162,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// There was a previous subslice pattern; make sure we don't allow more.
|
||||
let rest_span = match pat.kind {
|
||||
PatKind::Rest => Some(pat.span),
|
||||
PatKind::Ident(.., Some(ref sub)) if sub.is_rest() => {
|
||||
// The `HirValidator` is merciless; add a `_` pattern to avoid ICEs.
|
||||
after.push(self.pat_wild_with_node_id_of(pat));
|
||||
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
|
||||
// #69103: Lower into `binding @ _` as above to avoid ICEs.
|
||||
after.push(lower_rest_sub(self, pat, bm, ident, sub));
|
||||
Some(sub.span)
|
||||
}
|
||||
_ => None,
|
||||
|
@ -0,0 +1,18 @@
|
||||
// We used to not lower the extra `b @ ..` into `b @ _` which meant that no type
|
||||
// was registered for the binding `b` although it passed through resolve.
|
||||
// This resulted in an ICE (#69103).
|
||||
|
||||
fn main() {
|
||||
let [a @ .., b @ ..] = &mut [1, 2];
|
||||
//~^ ERROR `..` can only be used once per slice pattern
|
||||
b;
|
||||
|
||||
let [.., c @ ..] = [1, 2];
|
||||
//~^ ERROR `..` can only be used once per slice pattern
|
||||
c;
|
||||
|
||||
// This never ICEd, but let's make sure it won't regress either.
|
||||
let (.., d @ ..) = (1, 2);
|
||||
//~^ ERROR `..` patterns are not allowed here
|
||||
d;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
error: `..` can only be used once per slice pattern
|
||||
--> $DIR/issue-69103-extra-binding-subslice.rs:6:22
|
||||
|
|
||||
LL | let [a @ .., b @ ..] = &mut [1, 2];
|
||||
| -- ^^ can only be used once per slice pattern
|
||||
| |
|
||||
| previously used here
|
||||
|
||||
error: `..` can only be used once per slice pattern
|
||||
--> $DIR/issue-69103-extra-binding-subslice.rs:10:18
|
||||
|
|
||||
LL | let [.., c @ ..] = [1, 2];
|
||||
| -- ^^ can only be used once per slice pattern
|
||||
| |
|
||||
| previously used here
|
||||
|
||||
error: `..` patterns are not allowed here
|
||||
--> $DIR/issue-69103-extra-binding-subslice.rs:15:18
|
||||
|
|
||||
LL | let (.., d @ ..) = (1, 2);
|
||||
| ^^
|
||||
|
|
||||
= note: only allowed in tuple, tuple struct, and slice patterns
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user