Auto merge of #12409 - lowr:fix/usize-overflow, r=Veykril

fix overflow during type inference for tuple struct patterns

The following code causes integer overflow during type inference for (malformed) tuple struct patterns.

```rust
struct S(usize);
let S(.., a, b) = S(1);
```

It has been panicking only in debug builds, and working in a way in release builds but it was inconsistent with type inference for tuple patterns:

```rust
struct S(usize);
let S(.., a, b) = S(1); // a -> unknown, b -> usize
let (.., a, b) = (1,);  // a -> usize, b -> unknown
```

With this PR, the overflow no longer happens by utilizing `saturating_sub()` like in other places and type inference for tuple struct patterns is in line with that for tuple patterns.
This commit is contained in:
bors 2022-05-29 08:45:15 +00:00
commit f94fa62d69
2 changed files with 28 additions and 1 deletions

View file

@ -42,7 +42,7 @@ impl<'a> InferenceContext<'a> {
Some(idx) => subpats.split_at(idx),
None => (subpats, &[][..]),
};
let post_idx_offset = field_tys.iter().count() - post.len();
let post_idx_offset = field_tys.iter().count().saturating_sub(post.len());
let pre_iter = pre.iter().enumerate();
let post_iter = (post_idx_offset..).zip(post.iter());

View file

@ -1620,3 +1620,30 @@ pub trait Destruct {}
"#,
);
}
#[test]
fn tuple_struct_pattern_with_unmatched_args_crash() {
check_infer(
r#"
struct S(usize);
fn main() {
let S(.., a, b) = S(1);
let (.., a, b) = (1,);
}
"#,
expect![[r#"
27..85 '{ ...1,); }': ()
37..48 'S(.., a, b)': S
43..44 'a': usize
46..47 'b': {unknown}
51..52 'S': S(usize) -> S
51..55 'S(1)': S
53..54 '1': usize
65..75 '(.., a, b)': (i32, {unknown})
70..71 'a': i32
73..74 'b': {unknown}
78..82 '(1,)': (i32,)
79..80 '1': i32
"#]],
);
}