mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Implement more precise binary op return type prediction
This commit is contained in:
parent
e357b6bb36
commit
252eb78dc3
@ -9,21 +9,55 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
|
|||||||
BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
|
BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
|
||||||
BinaryOp::Assignment { .. } => TyBuilder::unit(),
|
BinaryOp::Assignment { .. } => TyBuilder::unit(),
|
||||||
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
|
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
|
||||||
match lhs_ty.kind(&Interner) {
|
// all integer combinations are valid here
|
||||||
|
if matches!(
|
||||||
|
lhs_ty.kind(&Interner),
|
||||||
TyKind::Scalar(Scalar::Int(_))
|
TyKind::Scalar(Scalar::Int(_))
|
||||||
| TyKind::Scalar(Scalar::Uint(_))
|
| TyKind::Scalar(Scalar::Uint(_))
|
||||||
| TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
|
| TyKind::InferenceVar(_, TyVariableKind::Integer)
|
||||||
TyKind::InferenceVar(_, TyVariableKind::Integer)
|
) && matches!(
|
||||||
| TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
|
rhs_ty.kind(&Interner),
|
||||||
_ => TyKind::Error.intern(&Interner),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BinaryOp::ArithOp(_) => match rhs_ty.kind(&Interner) {
|
|
||||||
TyKind::Scalar(Scalar::Int(_))
|
TyKind::Scalar(Scalar::Int(_))
|
||||||
| TyKind::Scalar(Scalar::Uint(_))
|
| TyKind::Scalar(Scalar::Uint(_))
|
||||||
| TyKind::Scalar(Scalar::Float(_)) => rhs_ty,
|
| TyKind::InferenceVar(_, TyVariableKind::Integer)
|
||||||
TyKind::InferenceVar(_, TyVariableKind::Integer)
|
) {
|
||||||
| TyKind::InferenceVar(_, TyVariableKind::Float) => rhs_ty,
|
lhs_ty
|
||||||
|
} else {
|
||||||
|
TyKind::Error.intern(&Interner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BinaryOp::ArithOp(_) => match (lhs_ty.kind(&Interner), rhs_ty.kind(&Interner)) {
|
||||||
|
// (int, int) | (uint, uint) | (float, float)
|
||||||
|
(TyKind::Scalar(Scalar::Int(_)), TyKind::Scalar(Scalar::Int(_)))
|
||||||
|
| (TyKind::Scalar(Scalar::Uint(_)), TyKind::Scalar(Scalar::Uint(_)))
|
||||||
|
| (TyKind::Scalar(Scalar::Float(_)), TyKind::Scalar(Scalar::Float(_))) => rhs_ty,
|
||||||
|
// ({int}, int) | ({int}, uint)
|
||||||
|
(TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Int(_)))
|
||||||
|
| (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Uint(_))) => {
|
||||||
|
rhs_ty
|
||||||
|
}
|
||||||
|
// (int, {int}) | (uint, {int})
|
||||||
|
(TyKind::Scalar(Scalar::Int(_)), TyKind::InferenceVar(_, TyVariableKind::Integer))
|
||||||
|
| (TyKind::Scalar(Scalar::Uint(_)), TyKind::InferenceVar(_, TyVariableKind::Integer)) => {
|
||||||
|
lhs_ty
|
||||||
|
}
|
||||||
|
// ({float} | float)
|
||||||
|
(TyKind::InferenceVar(_, TyVariableKind::Float), TyKind::Scalar(Scalar::Float(_))) => {
|
||||||
|
rhs_ty
|
||||||
|
}
|
||||||
|
// (float, {float})
|
||||||
|
(TyKind::Scalar(Scalar::Float(_)), TyKind::InferenceVar(_, TyVariableKind::Float)) => {
|
||||||
|
lhs_ty
|
||||||
|
}
|
||||||
|
// ({int}, {int}) | ({float}, {float})
|
||||||
|
(
|
||||||
|
TyKind::InferenceVar(_, TyVariableKind::Integer),
|
||||||
|
TyKind::InferenceVar(_, TyVariableKind::Integer),
|
||||||
|
)
|
||||||
|
| (
|
||||||
|
TyKind::InferenceVar(_, TyVariableKind::Float),
|
||||||
|
TyKind::InferenceVar(_, TyVariableKind::Float),
|
||||||
|
) => rhs_ty,
|
||||||
_ => TyKind::Error.intern(&Interner),
|
_ => TyKind::Error.intern(&Interner),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1936,14 +1936,14 @@ fn closure_2() {
|
|||||||
84..85 'f': F
|
84..85 'f': F
|
||||||
84..88 'f(1)': {unknown}
|
84..88 'f(1)': {unknown}
|
||||||
86..87 '1': i32
|
86..87 '1': i32
|
||||||
98..99 'g': |u64| -> i32
|
98..99 'g': |u64| -> {unknown}
|
||||||
102..111 '|v| v + 1': |u64| -> i32
|
102..111 '|v| v + 1': |u64| -> {unknown}
|
||||||
103..104 'v': u64
|
103..104 'v': u64
|
||||||
106..107 'v': u64
|
106..107 'v': u64
|
||||||
106..111 'v + 1': i32
|
106..111 'v + 1': {unknown}
|
||||||
110..111 '1': i32
|
110..111 '1': i32
|
||||||
117..118 'g': |u64| -> i32
|
117..118 'g': |u64| -> {unknown}
|
||||||
117..124 'g(1u64)': i32
|
117..124 'g(1u64)': {unknown}
|
||||||
119..123 '1u64': u64
|
119..123 '1u64': u64
|
||||||
134..135 'h': |u128| -> u128
|
134..135 'h': |u128| -> u128
|
||||||
138..151 '|v| 1u128 + v': |u128| -> u128
|
138..151 '|v| 1u128 + v': |u128| -> u128
|
||||||
|
Loading…
x
Reference in New Issue
Block a user