Change:
(a as Self, b) } <del> /// Calculates `self - rhs - borrow` without the ability to overflow. /// /// Performs "ternary subtraction" which takes in an extra bit to subtract, and may return /// an additional bit of overflow. This allows for chaining together multiple subtractions /// to create "big integers" which represent larger values. /// /// # Examples /// /// Basic usage /// /// ``` /// #![feature(bigint_helper_methods)] #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, false), (3, false));")] #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".borrowing_sub(2, true), (2, false));")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.borrowing_sub(1, false), (", stringify!($SelfT), "::MAX, false));")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.borrowing_sub(1, true), (", stringify!($SelfT), "::MAX - 1, false));")] /// ``` #[unstable(feature = "bigint_helper_methods", issue = "85532")] #[rustc_const_unstable(feature = "const_bigint_helper_methods", issue = "85532")] #[must_use = "this returns the result of the operation,  without modifying the original"] #[inline] pub const fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) { let (sum, borrow) = (self as $UnsignedT).borrowing_sub(rhs as $UnsignedT, borrow); (sum as $SelfT, borrow) } </del> /// Calculates `self` - `rhs` with an unsigned `rhs` /// /// Returns a tuple of the subtraction along with a boolean indicating

Discussion:
I had this question on the currently unreleased ; on signed carry (probably applies to substraction too ?); I have this test failing with the current code: Playground: Is the test correct ? A carry did happen in an intermediate calculation, but should the overall calculation report a carry ?
I agree that this is a bug. There's a carry when the calculation is done as unsigned, but this is not the same in signed. Another example: That incorrectly returns .
There's some discussion about that in the tracking issue, starting with
Yeah, it looks like I rehashed the same arguments, that's what I get for reading comments and doc too fast. Still, I think that this is surprising enough that it would be nice to address it somehow.
I agree this is a bug. It looks like it's implementing the signed version using the unsigned one, returning the same carry flag (), but that's incorrect. Here's another demonstration that it needs an update: you be up to making a fix PR, You can use to get assigned to this issue.
I have no bandwidth for making a fix right now. Since this was supposed to be helpers for bigint operations, my first idea was to just remove the signed variants. I have no idea if this would be appropriate. Anyone is welcome to do a proper fix, it shouldn't be too complicated.
A thought: What should do? It feels to me like the carryout from that should perhaps be , since the carry from that is different from the one in , which would imply that it couldn't be anymore. We do have a type that's -1, 0, or 1: . I can't decide if that's clever or horrible. Or should we just delete the signed versions for now?
I think should return , because signed and unsigned operations should give the same results, so should be computed as which gives , then truncated to 8-bits which gives . Then because gives , which can't be represented as an 8-bits signed number, then there is overflow to me. Now for the -1, 0, 1 overflow, I don't think it's necessary because the point of the bit is to indicate if it happened or not. The direction of overflow is indicated by the resulting value. If I am correct, then this raises another question: should intermediate overflow be detected or not ?

for example: gives a result of -128, so the output is the same as the input so no overflow. But if we break down the operations, overflows to 127, and then overflows back to -128. In this case should an overflow occur or not ? Considering my previous example, I personally think it intermediate overflow shouldn't be detected because it would be misleading: it would indicate that the sign of the source operands and the result are different while they are the same. Tho I'd like other's opinion.
I think so. The unsigned versions have clear semantics, but it gets weird with signed values, and as a "bigint helper" I'd be surprised to see one that uses signed digits in the first place.