]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #12409 - lowr:fix/usize-overflow, r=Veykril
authorbors <bors@rust-lang.org>
Sun, 29 May 2022 08:45:15 +0000 (08:45 +0000)
committerbors <bors@rust-lang.org>
Sun, 29 May 2022 08:45:15 +0000 (08:45 +0000)
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.

crates/hir-ty/src/infer/pat.rs
crates/hir-ty/src/tests/regression.rs

index dbce0f7cd4fb89e3ef0e0e7635ed690b7963a520..c06d262f5e3c2f2fcf6656939b725b163864eae6 100644 (file)
@@ -42,7 +42,7 @@ fn infer_tuple_struct_pat(
             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());
index ef27667ffa5729ee2c242a501ce17497afe0eadb..93f765f703ca0354dc4e6620a26d3148aee16f99 100644 (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
+        "#]],
+    );
+}