Change:
} }, ); <ins> let sign_bit_sub = (!negative) .then(|| { let ty::Int(int_ty) = cx.typeck_results().node_type(expr.hir_id).kind() else { return None; }; let Some(bit_width) = int_ty.bit_width() else { return None; // isize case }; // Skip if sign bit is not set if (val & (1 << (bit_width - 1))) == 0 { return None; } let lit_no_suffix = if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { repr_str.split_at(pos).0 } else { &repr_str }; Some(OverflowingBinHexSignBitSub { span: expr.span, lit_no_suffix, negative_val: actually.clone(), int_ty: int_ty.name_str(), uint_ty: int_ty.to_unsigned().name_str(), }) }) .flatten(); </ins> cx.emit_spanned_lint( OVERFLOWING_LITERALS, expr.span, <del> OverflowingBinHex { ty: t, lit: repr_str.clone(), dec: val, actually, sign, sub }, </del> <ins> OverflowingBinHex { ty: t, lit: repr_str.clone(), dec: val, actually, sign, sub, sign_bit_sub, }, </ins> ) }

Discussion:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected the code to compile since its i am assigning into x binary representation of i32::MIN, instead the compiler throws an error. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Similar issue happens with i16 as well where the below code dosen't compile
This looks intended to me. The binary literal , along with all other integer literals, represents the number in a more mathematical sense, instead of in a memory layout sense, so really means the integer , not (=)
A similar code compiles in c++ and hence I assumed it was a bug.
The C++ code works because C++ has implicit integer conversion. On a typical int = 32bit platform, means (in both rust and C++), and is typed in C++ (because it doesn't fit in . "The type of the integer literal is the first type in which the value can fit"), and then when you assign it back to int32_t, the result is {implementation-defined (C++17 or earlier)} / {reinterpreted in terms of 2's complement(C++20 or later)}, which gives you back i32::MIN. Its rust equivalent code should be
Ohh okay. Thanks for this information. Now I too feel that this behavior was intentional.
So it sounds like the problem here is that the diagnostic doesn't teach all this.
A nice diagnostic would be that, if an overflowing literal has "sign bit" set, guess the user wants to express a negative number in 2's complement, and suggest using the negative number literal
I can try and give this a shot. claim
Thus that very weird and probably a bad practice in most case. Doing binary operation on signed number is never a good thing in my book.

In that case, the compiler emits an error if you do it at compile-time since it's a case of the operation inducing wraparound (which lands on the same value). That's not a satisfying answer as to why the mere literal fails to compile.
Sorry, I haven't had the time to work on this. Releasing in hopes someone can pick it up. release-assignment
I'd like to give this a try, but I need some assistance as I have no experience working on the compiler. claim My idea is to add another and when the literal fits in the unsigned variant, but not the signed variant (in the provided example, and respectively) Facing a blocker now. How could one emit multiple suggestions (that share the same span) or "help"s? Would love to hear suggestions or guidance :)
Thank you all for closing this