https://gcc.gnu.org/g:c3ed90196ca7ed06ee2b38e5b7523516487bd65e
commit r17-5709-gc3ed90196ca7ed06ee2b38e5b7523516487bd65e Author: Yap Zhi Heng <[email protected]> Date: Sun Oct 25 22:24:48 2026 +0800 gccrs: Fix bitshift compound assignment type check 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]> Diff: --- gcc/rust/typecheck/rust-hir-type-check-expr.cc | 27 +++++++++++++++++++------- gcc/testsuite/rust/compile/issues/4913.rs | 22 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index f420eb6f0a02..44487f532674 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 000000000000..57e334f11955 --- /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
