Skip to content

Commit e75e2f8

Browse files
committed
Auto merge of rust-lang#13882 - Veykril:bin-op-adjust, r=Veykril
Write down adjustments introduced by binary operators
2 parents 17cc78f + 506895f commit e75e2f8

File tree

6 files changed

+86
-21
lines changed

6 files changed

+86
-21
lines changed

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

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{
66
};
77

88
use chalk_ir::{
9-
cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyVariableKind,
9+
cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyKind, TyVariableKind,
1010
};
1111
use hir_def::{
1212
expr::{
@@ -34,8 +34,8 @@ use crate::{
3434
primitive::{self, UintTy},
3535
static_lifetime, to_chalk_trait_id,
3636
utils::{generics, Generics},
37-
AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, Interner, Rawness, Scalar,
38-
Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
37+
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnPointer, FnSig, FnSubst,
38+
Interner, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt,
3939
};
4040

4141
use super::{
@@ -1038,14 +1038,38 @@ impl<'a> InferenceContext<'a> {
10381038
self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone()));
10391039

10401040
let ret_ty = match method_ty.callable_sig(self.db) {
1041-
Some(sig) => sig.ret().clone(),
1041+
Some(sig) => {
1042+
let p_left = &sig.params()[0];
1043+
if matches!(op, BinaryOp::CmpOp(..) | BinaryOp::Assignment { .. }) {
1044+
if let &TyKind::Ref(mtbl, _, _) = p_left.kind(Interner) {
1045+
self.write_expr_adj(
1046+
lhs,
1047+
vec![Adjustment {
1048+
kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
1049+
target: p_left.clone(),
1050+
}],
1051+
);
1052+
}
1053+
}
1054+
let p_right = &sig.params()[1];
1055+
if matches!(op, BinaryOp::CmpOp(..)) {
1056+
if let &TyKind::Ref(mtbl, _, _) = p_right.kind(Interner) {
1057+
self.write_expr_adj(
1058+
rhs,
1059+
vec![Adjustment {
1060+
kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
1061+
target: p_right.clone(),
1062+
}],
1063+
);
1064+
}
1065+
}
1066+
sig.ret().clone()
1067+
}
10421068
None => self.err_ty(),
10431069
};
10441070

10451071
let ret_ty = self.normalize_associated_types_in(ret_ty);
10461072

1047-
// FIXME: record autoref adjustments
1048-
10491073
// use knowledge of built-in binary ops, which can sometimes help inference
10501074
if let Some(builtin_rhs) = self.builtin_binary_op_rhs_expectation(op, lhs_ty.clone()) {
10511075
self.unify(&builtin_rhs, &rhs_ty);

crates/hir-ty/src/tests.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,12 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
9494
types.insert(file_range, expected.trim_start_matches("type: ").to_string());
9595
} else if expected.starts_with("expected") {
9696
mismatches.insert(file_range, expected);
97-
} else if expected.starts_with("adjustments: ") {
97+
} else if expected.starts_with("adjustments:") {
9898
adjustments.insert(
9999
file_range,
100100
expected
101-
.trim_start_matches("adjustments: ")
101+
.trim_start_matches("adjustments:")
102+
.trim()
102103
.split(',')
103104
.map(|it| it.trim().to_string())
104105
.filter(|it| !it.is_empty())
@@ -176,17 +177,17 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
176177
assert_eq!(actual, expected);
177178
}
178179
if let Some(expected) = adjustments.remove(&range) {
179-
if let Some(adjustments) = inference_result.expr_adjustments.get(&expr) {
180-
assert_eq!(
181-
expected,
182-
adjustments
183-
.iter()
184-
.map(|Adjustment { kind, .. }| format!("{kind:?}"))
185-
.collect::<Vec<_>>()
186-
);
187-
} else {
188-
panic!("expected {expected:?} adjustments, found none");
189-
}
180+
let adjustments = inference_result
181+
.expr_adjustments
182+
.get(&expr)
183+
.map_or_else(Default::default, |it| &**it);
184+
assert_eq!(
185+
expected,
186+
adjustments
187+
.iter()
188+
.map(|Adjustment { kind, .. }| format!("{kind:?}"))
189+
.collect::<Vec<_>>()
190+
);
190191
}
191192
}
192193

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,3 +807,37 @@ fn main() {
807807
"#,
808808
);
809809
}
810+
811+
#[test]
812+
fn adjust_comparison_arguments() {
813+
check_no_mismatches(
814+
r"
815+
//- minicore: eq
816+
struct Struct;
817+
impl core::cmp::PartialEq for Struct {
818+
fn eq(&self, other: &Self) -> bool { true }
819+
}
820+
fn test() {
821+
Struct == Struct;
822+
// ^^^^^^ adjustments: Borrow(Ref(Not))
823+
// ^^^^^^ adjustments: Borrow(Ref(Not))
824+
}",
825+
);
826+
}
827+
828+
#[test]
829+
fn adjust_assign_lhs() {
830+
check_no_mismatches(
831+
r"
832+
//- minicore: add
833+
struct Struct;
834+
impl core::ops::AddAssign for Struct {
835+
fn add_assign(&mut self, other: Self) {}
836+
}
837+
fn test() {
838+
Struct += Struct;
839+
// ^^^^^^ adjustments: Borrow(Ref(Mut))
840+
// ^^^^^^ adjustments:
841+
}",
842+
);
843+
}

crates/ide/src/inlay_hints.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ mod chaining;
2424
mod param_name;
2525
mod binding_mode;
2626
mod bind_pat;
27-
mod discrimant;
27+
mod discriminant;
2828

2929
#[derive(Clone, Debug, PartialEq, Eq)]
3030
pub struct InlayHintsConfig {
@@ -376,7 +376,7 @@ fn hints(
376376
_ => None,
377377
},
378378
ast::Variant(v) => {
379-
discrimant::hints(hints, famous_defs, config, file_id, &v)
379+
discriminant::hints(hints, famous_defs, config, file_id, &v)
380380
},
381381
// FIXME: fn-ptr type, dyn fn type, and trait object type elisions
382382
ast::Type(_) => None,

crates/test-utils/src/minicore.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,12 @@ pub mod ops {
382382
type Output;
383383
fn add(self, rhs: Rhs) -> Self::Output;
384384
}
385+
386+
#[lang = "add_assign"]
387+
#[const_trait]
388+
pub trait AddAssign<Rhs = Self> {
389+
fn add_assign(&mut self, rhs: Rhs);
390+
}
385391
// endregion:add
386392

387393
// region:generator

0 commit comments

Comments
 (0)