From<bool> and Bounded's invariant for signed N = 1
Hi,
There seems to be an invariant violation in the generic From<bool> implementation for Bounded.
As I understand it, Bounded<i8, 1> can represent only -1 and 0, while i8::from(true) produces 1. However, this safe code is accepted:
let value: Bounded<i8, 1> = true.into();
let _raw: i8 = *value;
Bounded::<i8, 1>::try_new(1) rejects the same value, but From<bool> passes it directly to the unsafe __new() constructor. The resulting Bounded value violates the invariant relied upon by Deref, whose failure branch calls unreachable_unchecked().
Am I missing an intended constraint on this conversion? If not, it seems the signed N = 1 case needs to be excluded or handled differently.
Any thoughts?
Thanks,
Younes
Quoted 2 lines · Younes Akhouayri
Any thoughts?
Thanks for the report!
That is correct, good eyes -- indeed, the Deref bites us again like in 223aa25aee82.
Do you want to write a patch?
Cheers,
Miguel
Alexandre Courbot
reviewerQuoted 16 lines · Younes Akhouayri
Hi,
There seems to be an invariant violation in the generic From<bool> implementation for Bounded.
As I understand it, Bounded<i8, 1> can represent only -1 and 0, while
i8::from(true)produces 1. However, this safe code is accepted:let value: Bounded<i8, 1> =
true.into();
let_raw: i8 = *value;Bounded::<i8, 1>::try_new(1) rejects the same value, but From<bool> passes it directly to the unsafe
__new()constructor. The resulting Bounded value violates the invariant relied upon by Deref, whose failure branch callsunreachable_unchecked().
Quoted 5 lines
Am I missing an intended constraint on this conversion? If not, it seems the signed N = 1 case needs to be excluded or handled differently.
Any thoughts?
I think you are correct. There is a Signedness associated type on the Integer trait, so it should be trivial to exclude signed integers - do you want to send a patch for that?
Thank you both for the feedback. Yes, I can send a patch.
Just to confirm the intended scope: excluding signed integers entirely would also remove valid conversions such as Bounded::<i8, 2>::from(true), since signed Bounded values with N >= 2 can represent both 0 and 1.
Would you prefer the simpler unsigned-only restriction, or should the patch preserve signed conversions for N >= 2?
--
Best regards,
Younes
Aug 13, 2026, 15:04 by [email protected]:
Quoted 29 lines · Younes Akhouayri
Quoted 17 lines
Hi,
There seems to be an invariant violation in the generic From<bool> implementation for Bounded.
As I understand it, Bounded<i8, 1> can represent only -1 and 0, while
i8::from(true)produces 1. However, this safe code is accepted:let value: Bounded<i8, 1> =
true.into();
let_raw: i8 = *value;Bounded::<i8, 1>::try_new(1) rejects the same value, but From<bool> passes it directly to the unsafe
__new()constructor. The resulting Bounded value violates the invariant relied upon by Deref, whose failure branch callsunreachable_unchecked().Quoted 6 lines
Am I missing an intended constraint on this conversion? If not, it seems the signed N = 1 case needs to be excluded or handled differently.
Any thoughts?
I think you are correct. There is a
Signednessassociated type on theIntegertrait, so it should be trivial to exclude signed integers - do you want to send a patch for that?
Alexandre Courbot
reviewerQuoted 5 lines · Younes Akhouayri
Thank you both for the feedback. Yes, I can send a patch.
Just to confirm the intended scope: excluding signed integers entirely would also remove valid conversions such as Bounded::<i8, 2>::from(true), since signed Bounded values with N >= 2 can represent both 0 and 1.
Would you prefer the simpler unsigned-only restriction, or should the patch preserve signed conversions for N >= 2?
If you can preserve the latter without complicating the code too much, then I'd say that should be preferred yes.