Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/infer/op.rs12
-rw-r--r--crates/hir-ty/src/tests/never_type.rs31
2 files changed, 39 insertions, 4 deletions
diff --git a/crates/hir-ty/src/infer/op.rs b/crates/hir-ty/src/infer/op.rs
index c79c828cd4..95d63ffb50 100644
--- a/crates/hir-ty/src/infer/op.rs
+++ b/crates/hir-ty/src/infer/op.rs
@@ -178,9 +178,9 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
// trait matching creating lifetime constraints that are too strict.
// e.g., adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
// in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
- let lhs_ty = self.infer_expr_no_expect(lhs_expr, ExprIsRead::No);
+ let lhs_ty = self.infer_expr_no_expect(lhs_expr, ExprIsRead::Yes);
let fresh_var = self.table.next_ty_var();
- self.demand_coerce(lhs_expr, lhs_ty, fresh_var, AllowTwoPhase::No, ExprIsRead::No)
+ self.demand_coerce(lhs_expr, lhs_ty, fresh_var, AllowTwoPhase::No, ExprIsRead::Yes)
}
};
let lhs_ty = self.table.resolve_vars_with_obligations(lhs_ty);
@@ -200,7 +200,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
// see `NB` above
let rhs_ty =
- self.infer_expr_coerce(rhs_expr, &Expectation::HasType(rhs_ty_var), ExprIsRead::No);
+ self.infer_expr_coerce(rhs_expr, &Expectation::HasType(rhs_ty_var), ExprIsRead::Yes);
let rhs_ty = self.table.resolve_vars_with_obligations(rhs_ty);
let return_ty = match result {
@@ -320,7 +320,11 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
if let Some((rhs_expr, rhs_ty)) = opt_rhs
&& rhs_ty.is_ty_var()
{
- self.infer_expr_coerce(rhs_expr, &Expectation::HasType(rhs_ty), ExprIsRead::No);
+ self.infer_expr_coerce(
+ rhs_expr,
+ &Expectation::HasType(rhs_ty),
+ ExprIsRead::Yes,
+ );
}
// Construct an obligation `self_ty : Trait<input_tys>`
diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs
index e4e7b4cc38..1ff803ca42 100644
--- a/crates/hir-ty/src/tests/never_type.rs
+++ b/crates/hir-ty/src/tests/never_type.rs
@@ -803,6 +803,37 @@ fn foo() {
}
#[test]
+fn binop_rhs_never_place_diverges() {
+ check_no_mismatches(
+ r#"
+//- minicore: sized, add
+fn foo() -> i32 {
+ unsafe {
+ let p: *mut ! = 0 as _;
+ let mut x: i32 = 0;
+ x += *p;
+ }
+}
+"#,
+ );
+}
+
+#[test]
+fn binop_lhs_never_place_diverges() {
+ check_no_mismatches(
+ r#"
+//- minicore: sized, add
+fn foo() {
+ unsafe {
+ let p: *mut ! = 0 as _;
+ *p += 1;
+ }
+}
+"#,
+ );
+}
+
+#[test]
fn never_place_isnt_diverging() {
check_infer_with_mismatches(
r#"