mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Auto merge of #13882 - Veykril:bin-op-adjust, r=Veykril
Write down adjustments introduced by binary operators
This commit is contained in:
commit
e75e2f8368
@ -6,7 +6,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use chalk_ir::{
|
use chalk_ir::{
|
||||||
cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyVariableKind,
|
cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyKind, TyVariableKind,
|
||||||
};
|
};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
expr::{
|
expr::{
|
||||||
@ -34,8 +34,8 @@ use crate::{
|
|||||||
primitive::{self, UintTy},
|
primitive::{self, UintTy},
|
||||||
static_lifetime, to_chalk_trait_id,
|
static_lifetime, to_chalk_trait_id,
|
||||||
utils::{generics, Generics},
|
utils::{generics, Generics},
|
||||||
AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, Interner, Rawness, Scalar,
|
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnPointer, FnSig, FnSubst,
|
||||||
Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
|
Interner, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -1038,14 +1038,38 @@ impl<'a> InferenceContext<'a> {
|
|||||||
self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone()));
|
self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone()));
|
||||||
|
|
||||||
let ret_ty = match method_ty.callable_sig(self.db) {
|
let ret_ty = match method_ty.callable_sig(self.db) {
|
||||||
Some(sig) => sig.ret().clone(),
|
Some(sig) => {
|
||||||
|
let p_left = &sig.params()[0];
|
||||||
|
if matches!(op, BinaryOp::CmpOp(..) | BinaryOp::Assignment { .. }) {
|
||||||
|
if let &TyKind::Ref(mtbl, _, _) = p_left.kind(Interner) {
|
||||||
|
self.write_expr_adj(
|
||||||
|
lhs,
|
||||||
|
vec![Adjustment {
|
||||||
|
kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
|
||||||
|
target: p_left.clone(),
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let p_right = &sig.params()[1];
|
||||||
|
if matches!(op, BinaryOp::CmpOp(..)) {
|
||||||
|
if let &TyKind::Ref(mtbl, _, _) = p_right.kind(Interner) {
|
||||||
|
self.write_expr_adj(
|
||||||
|
rhs,
|
||||||
|
vec![Adjustment {
|
||||||
|
kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
|
||||||
|
target: p_right.clone(),
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sig.ret().clone()
|
||||||
|
}
|
||||||
None => self.err_ty(),
|
None => self.err_ty(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret_ty = self.normalize_associated_types_in(ret_ty);
|
let ret_ty = self.normalize_associated_types_in(ret_ty);
|
||||||
|
|
||||||
// FIXME: record autoref adjustments
|
|
||||||
|
|
||||||
// use knowledge of built-in binary ops, which can sometimes help inference
|
// use knowledge of built-in binary ops, which can sometimes help inference
|
||||||
if let Some(builtin_rhs) = self.builtin_binary_op_rhs_expectation(op, lhs_ty.clone()) {
|
if let Some(builtin_rhs) = self.builtin_binary_op_rhs_expectation(op, lhs_ty.clone()) {
|
||||||
self.unify(&builtin_rhs, &rhs_ty);
|
self.unify(&builtin_rhs, &rhs_ty);
|
||||||
|
@ -94,11 +94,12 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
|
|||||||
types.insert(file_range, expected.trim_start_matches("type: ").to_string());
|
types.insert(file_range, expected.trim_start_matches("type: ").to_string());
|
||||||
} else if expected.starts_with("expected") {
|
} else if expected.starts_with("expected") {
|
||||||
mismatches.insert(file_range, expected);
|
mismatches.insert(file_range, expected);
|
||||||
} else if expected.starts_with("adjustments: ") {
|
} else if expected.starts_with("adjustments:") {
|
||||||
adjustments.insert(
|
adjustments.insert(
|
||||||
file_range,
|
file_range,
|
||||||
expected
|
expected
|
||||||
.trim_start_matches("adjustments: ")
|
.trim_start_matches("adjustments:")
|
||||||
|
.trim()
|
||||||
.split(',')
|
.split(',')
|
||||||
.map(|it| it.trim().to_string())
|
.map(|it| it.trim().to_string())
|
||||||
.filter(|it| !it.is_empty())
|
.filter(|it| !it.is_empty())
|
||||||
@ -176,17 +177,17 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
|
|||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
if let Some(expected) = adjustments.remove(&range) {
|
if let Some(expected) = adjustments.remove(&range) {
|
||||||
if let Some(adjustments) = inference_result.expr_adjustments.get(&expr) {
|
let adjustments = inference_result
|
||||||
assert_eq!(
|
.expr_adjustments
|
||||||
expected,
|
.get(&expr)
|
||||||
adjustments
|
.map_or_else(Default::default, |it| &**it);
|
||||||
.iter()
|
assert_eq!(
|
||||||
.map(|Adjustment { kind, .. }| format!("{kind:?}"))
|
expected,
|
||||||
.collect::<Vec<_>>()
|
adjustments
|
||||||
);
|
.iter()
|
||||||
} else {
|
.map(|Adjustment { kind, .. }| format!("{kind:?}"))
|
||||||
panic!("expected {expected:?} adjustments, found none");
|
.collect::<Vec<_>>()
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,3 +807,37 @@ fn main() {
|
|||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn adjust_comparison_arguments() {
|
||||||
|
check_no_mismatches(
|
||||||
|
r"
|
||||||
|
//- minicore: eq
|
||||||
|
struct Struct;
|
||||||
|
impl core::cmp::PartialEq for Struct {
|
||||||
|
fn eq(&self, other: &Self) -> bool { true }
|
||||||
|
}
|
||||||
|
fn test() {
|
||||||
|
Struct == Struct;
|
||||||
|
// ^^^^^^ adjustments: Borrow(Ref(Not))
|
||||||
|
// ^^^^^^ adjustments: Borrow(Ref(Not))
|
||||||
|
}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn adjust_assign_lhs() {
|
||||||
|
check_no_mismatches(
|
||||||
|
r"
|
||||||
|
//- minicore: add
|
||||||
|
struct Struct;
|
||||||
|
impl core::ops::AddAssign for Struct {
|
||||||
|
fn add_assign(&mut self, other: Self) {}
|
||||||
|
}
|
||||||
|
fn test() {
|
||||||
|
Struct += Struct;
|
||||||
|
// ^^^^^^ adjustments: Borrow(Ref(Mut))
|
||||||
|
// ^^^^^^ adjustments:
|
||||||
|
}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -24,7 +24,7 @@ mod chaining;
|
|||||||
mod param_name;
|
mod param_name;
|
||||||
mod binding_mode;
|
mod binding_mode;
|
||||||
mod bind_pat;
|
mod bind_pat;
|
||||||
mod discrimant;
|
mod discriminant;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct InlayHintsConfig {
|
pub struct InlayHintsConfig {
|
||||||
@ -376,7 +376,7 @@ fn hints(
|
|||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
ast::Variant(v) => {
|
ast::Variant(v) => {
|
||||||
discrimant::hints(hints, famous_defs, config, file_id, &v)
|
discriminant::hints(hints, famous_defs, config, file_id, &v)
|
||||||
},
|
},
|
||||||
// FIXME: fn-ptr type, dyn fn type, and trait object type elisions
|
// FIXME: fn-ptr type, dyn fn type, and trait object type elisions
|
||||||
ast::Type(_) => None,
|
ast::Type(_) => None,
|
||||||
|
@ -382,6 +382,12 @@ pub mod ops {
|
|||||||
type Output;
|
type Output;
|
||||||
fn add(self, rhs: Rhs) -> Self::Output;
|
fn add(self, rhs: Rhs) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[lang = "add_assign"]
|
||||||
|
#[const_trait]
|
||||||
|
pub trait AddAssign<Rhs = Self> {
|
||||||
|
fn add_assign(&mut self, rhs: Rhs);
|
||||||
|
}
|
||||||
// endregion:add
|
// endregion:add
|
||||||
|
|
||||||
// region:generator
|
// region:generator
|
||||||
|
Loading…
Reference in New Issue
Block a user