Skip to content

Commit c0d8e34

Browse files
committed
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.
1 parent a78e873 commit c0d8e34

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ impl<'db> InferenceContext<'_, 'db> {
751751

752752
if let Some(lhs_ty) = lhs_ty {
753753
self.write_pat_ty(target, lhs_ty);
754-
self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::No);
754+
self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::Yes);
755755
} else {
756756
let rhs_ty = self.infer_expr(value, &Expectation::none(), ExprIsRead::Yes);
757757
let resolver_guard =

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,22 @@ fn coerce_ref_mut_binding() -> ! {
786786
)
787787
}
788788

789+
#[test]
790+
fn assign_never_place_no_mismatch() {
791+
check_no_mismatches(
792+
r#"
793+
//- minicore: sized
794+
fn foo() {
795+
unsafe {
796+
let p: *mut ! = 0 as _;
797+
let mut x: () = ();
798+
x = *p;
799+
}
800+
}
801+
"#,
802+
);
803+
}
804+
789805
#[test]
790806
fn never_place_isnt_diverging() {
791807
check_infer_with_mismatches(

0 commit comments

Comments
 (0)