Unnamed repository; edit this file 'description' to name the repository.
fix: use `ExprIsRead::Yes` for rhs of ordinary assignments
the rhs of an ordinary assignment `x = *never_ptr` was inferred with `ExprIsRead::No`, which prevented `NeverToAny` coercion for place expressions of type `!`. this caused false type mismatches and missing divergence detection. the destructuring assignment path and let binding path both correctly use `ExprIsRead::Yes` for the rhs value, since the value is always consumed (read). this makes the ordinary assignment path consistent with both.
Albab-Hasan 2 months ago
parent a78e873 · commit c0d8e34
-rw-r--r--crates/hir-ty/src/infer/expr.rs2
-rw-r--r--crates/hir-ty/src/tests/never_type.rs16
2 files changed, 17 insertions, 1 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 9f2d9d25b9..16e7d51e87 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -751,7 +751,7 @@ impl<'db> InferenceContext<'_, 'db> {
if let Some(lhs_ty) = lhs_ty {
self.write_pat_ty(target, lhs_ty);
- self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::No);
+ self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::Yes);
} else {
let rhs_ty = self.infer_expr(value, &Expectation::none(), ExprIsRead::Yes);
let resolver_guard =
diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs
index a89d97984d..e4e7b4cc38 100644
--- a/crates/hir-ty/src/tests/never_type.rs
+++ b/crates/hir-ty/src/tests/never_type.rs
@@ -787,6 +787,22 @@ fn coerce_ref_mut_binding() -> ! {
}
#[test]
+fn assign_never_place_no_mismatch() {
+ check_no_mismatches(
+ r#"
+//- minicore: sized
+fn foo() {
+ unsafe {
+ let p: *mut ! = 0 as _;
+ let mut x: () = ();
+ x = *p;
+ }
+}
+"#,
+ );
+}
+
+#[test]
fn never_place_isnt_diverging() {
check_infer_with_mismatches(
r#"