Skip to content

Commit f94fa62

Browse files
committed
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.
2 parents 6c9fc4f + be2fa2b commit f94fa62

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl<'a> InferenceContext<'a> {
4242
Some(idx) => subpats.split_at(idx),
4343
None => (subpats, &[][..]),
4444
};
45-
let post_idx_offset = field_tys.iter().count() - post.len();
45+
let post_idx_offset = field_tys.iter().count().saturating_sub(post.len());
4646

4747
let pre_iter = pre.iter().enumerate();
4848
let post_iter = (post_idx_offset..).zip(post.iter());

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

+27
Original file line numberDiff line numberDiff line change
@@ -1620,3 +1620,30 @@ pub trait Destruct {}
16201620
"#,
16211621
);
16221622
}
1623+
1624+
#[test]
1625+
fn tuple_struct_pattern_with_unmatched_args_crash() {
1626+
check_infer(
1627+
r#"
1628+
struct S(usize);
1629+
fn main() {
1630+
let S(.., a, b) = S(1);
1631+
let (.., a, b) = (1,);
1632+
}
1633+
"#,
1634+
expect![[r#"
1635+
27..85 '{ ...1,); }': ()
1636+
37..48 'S(.., a, b)': S
1637+
43..44 'a': usize
1638+
46..47 'b': {unknown}
1639+
51..52 'S': S(usize) -> S
1640+
51..55 'S(1)': S
1641+
53..54 '1': usize
1642+
65..75 '(.., a, b)': (i32, {unknown})
1643+
70..71 'a': i32
1644+
73..74 'b': {unknown}
1645+
78..82 '(1,)': (i32,)
1646+
79..80 '1': i32
1647+
"#]],
1648+
);
1649+
}

0 commit comments

Comments
 (0)