Unnamed repository; edit this file 'description' to name the repository.
fix: handle `ref mut` bindings in `contains_explicit_ref_binding`
the standalone `contains_explicit_ref_binding` function only checked for `BindingAnnotation::Ref`, missing `BindingAnnotation::RefMut`. this caused `let ref mut x = expr` to incorrectly take the coercion path instead of preserving the exact type of the rhs expression. the method version used for match arms already handles both `Ref` and `RefMut` correctly.
Albab-Hasan 2 months ago
parent b7d3e7b · commit a78e873
-rw-r--r--crates/hir-ty/src/infer/pat.rs2
-rw-r--r--crates/hir-ty/src/tests/never_type.rs26
2 files changed, 27 insertions, 1 deletions
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index 1b8ce5ceaf..87fd0dace3 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -673,7 +673,7 @@ impl<'db> InferenceContext<'_, 'db> {
pub(super) fn contains_explicit_ref_binding(body: &Body, pat_id: PatId) -> bool {
let mut res = false;
body.walk_pats(pat_id, &mut |pat| {
- res |= matches!(body[pat], Pat::Bind { id, .. } if body[id].mode == BindingAnnotation::Ref);
+ res |= matches!(body[pat], Pat::Bind { id, .. } if matches!(body[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut));
});
res
}
diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs
index 4d68179a88..a89d97984d 100644
--- a/crates/hir-ty/src/tests/never_type.rs
+++ b/crates/hir-ty/src/tests/never_type.rs
@@ -761,6 +761,32 @@ fn coerce_ref_binding() -> ! {
}
#[test]
+fn diverging_place_match_ref_mut() {
+ check_infer_with_mismatches(
+ r#"
+//- minicore: sized
+fn coerce_ref_mut_binding() -> ! {
+ unsafe {
+ let x: *mut ! = 0 as _;
+ let ref mut _x: () = *x;
+ }
+}
+"#,
+ expect![[r#"
+ 33..120 '{ ... } }': !
+ 39..118 'unsafe... }': !
+ 60..61 'x': *mut !
+ 72..73 '0': i32
+ 72..78 '0 as _': *mut !
+ 92..102 'ref mut _x': &'? mut ()
+ 109..111 '*x': !
+ 110..111 'x': *mut !
+ 109..111: expected (), got !
+ "#]],
+ )
+}
+
+#[test]
fn never_place_isnt_diverging() {
check_infer_with_mismatches(
r#"