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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/50e4287ffea164c6fa50e37011ffee08664cc239

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/5017

 .../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 f420eb6f0..44487f532 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 000000000..57e334f11
--- /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

base-commit: fe109d6e5196e62d1e092d1f1e0b172d381461ed
-- 
2.55.0

Reply via email to