Skip to content

Commit d1d91df

Browse files
Merge #2870
2870: Fix inference for shift operators r=matklad a=flodiebold Fixes #2602. Co-authored-by: Florian Diebold <[email protected]>
2 parents 07dca11 + 33d637f commit d1d91df

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

crates/ra_hir_ty/src/infer/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
386386
let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
387387
// FIXME: find implementation of trait corresponding to operation
388388
// symbol and resolve associated `Output` type
389-
let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty);
389+
let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone());
390390
let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
391391

392392
// FIXME: similar as above, return ty is often associated trait type
393-
op::binary_op_return_ty(*op, rhs_ty)
393+
op::binary_op_return_ty(*op, lhs_ty, rhs_ty)
394394
}
395395
_ => Ty::Unknown,
396396
},

crates/ra_hir_ty/src/op.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
//! FIXME: write short doc here
2-
use hir_def::expr::{BinaryOp, CmpOp};
1+
//! Helper functions for binary operator type inference.
2+
use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
33

44
use super::{InferTy, Ty, TypeCtor};
55
use crate::ApplicationTy;
66

7-
pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
7+
pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
88
match op {
99
BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool),
1010
BinaryOp::Assignment { .. } => Ty::unit(),
11+
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty {
12+
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
13+
TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty,
14+
_ => Ty::Unknown,
15+
},
16+
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
17+
_ => Ty::Unknown,
18+
},
1119
BinaryOp::ArithOp(_) => match rhs_ty {
1220
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
1321
TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty,
@@ -36,6 +44,7 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
3644
_ => Ty::Unknown,
3745
}
3846
}
47+
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown,
3948
BinaryOp::CmpOp(CmpOp::Ord { .. })
4049
| BinaryOp::Assignment { op: Some(_) }
4150
| BinaryOp::ArithOp(_) => match lhs_ty {

crates/ra_hir_ty/src/tests/simple.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,27 @@ fn test() -> bool {
613613
);
614614
}
615615

616+
#[test]
617+
fn infer_shift_op() {
618+
assert_snapshot!(
619+
infer(r#"
620+
fn test() {
621+
1u32 << 5u8;
622+
1u32 >> 5u8;
623+
}
624+
"#),
625+
@r###"
626+
[11; 48) '{ ...5u8; }': ()
627+
[17; 21) '1u32': u32
628+
[17; 28) '1u32 << 5u8': u32
629+
[25; 28) '5u8': u8
630+
[34; 38) '1u32': u32
631+
[34; 45) '1u32 >> 5u8': u32
632+
[42; 45) '5u8': u8
633+
"###
634+
);
635+
}
636+
616637
#[test]
617638
fn infer_field_autoderef() {
618639
assert_snapshot!(

0 commit comments

Comments
 (0)