From: Yap Zhi Heng <[email protected]>
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-expr.cc
(TypeCheckExpr::visit (HIR::CompoundAssignmentExpr)): For bitshift
cases,
cast rhs to lhs, similar to how ArithmeticOrLogicalExpr handles bitshift
cases too.
Signed-off-by: Yap Zhi Heng <[email protected]>
Tested on x86_64-pc-linux-gnu.
---
.../typecheck/rust-hir-type-check-expr.cc | 27 ++++++++++++++-----
gcc/testsuite/rust/compile/issues/4913.rs | 22 +++++++++++++++
2 files changed, 42 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/issues/4913.rs
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index f420eb6f0a0..44487f53267 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -419,13 +419,6 @@ TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr)
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
- // we dont care about the result of the unify from a compound assignment
- // since this is a unit-type expr
- coercion_site (expr.get_mappings ().get_hirid (),
- TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
- TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
- expr.get_locus ());
-
auto lang_item_type
= LangItem::CompoundAssignmentOperatorToLangItem (expr.get_expr_type ());
bool operator_overloaded
@@ -444,6 +437,26 @@ TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr)
lhs->as_string ().c_str (), rhs->as_string ().c_str ());
return;
}
+
+ switch (expr.get_expr_type ())
+ {
+ case ArithmeticOrLogicalOperator::LEFT_SHIFT:
+ case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
+ {
+ TyTy::TyWithLocation from (rhs, expr.get_rhs ().get_locus ());
+ TyTy::TyWithLocation to (lhs, expr.get_lhs ().get_locus ());
+ cast_site (expr.get_mappings ().get_hirid (), from, to,
+ expr.get_locus ());
+ break;
+ }
+ default:
+ // we dont care about the result of the unify from a compound assignment
+ // since this is a unit-type expr
+ coercion_site (expr.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()),
+ TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()),
+ expr.get_locus ());
+ }
}
void
diff --git a/gcc/testsuite/rust/compile/issues/4913.rs
b/gcc/testsuite/rust/compile/issues/4913.rs
new file mode 100644
index 00000000000..57e334f1195
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issues/4913.rs
@@ -0,0 +1,22 @@
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+impl u32 {
+ pub const BITS: u32 = 32;
+}
+
+fn from_u64(mut v: u64) -> u64 {
+ let mut sz: u64 = 0;
+ while v > 0 {
+ v >>= <u32>::BITS;
+ sz += 1;
+ }
+ sz
+}
+
+fn main() {
+ let _ = from_u64(5);
+}
\ No newline at end of file
--
2.55.0