[ty] Fix subtraction overflow bug

PR #21549 introduced a subtle overflow bug that seemed impossible, but
can empirically happen. This PR fixes it by saturating to zero.

I did try to write a regression test for this, but couldn't manage it.
Instead, I'll attach before-and-after screen recordings.
This commit is contained in:
Andrew Gallant 2025-11-21 14:02:12 -05:00 committed by Andrew Gallant
parent 6cc502781f
commit 438ef334d3
2 changed files with 20 additions and 1 deletions

View File

@ -106,6 +106,25 @@ impl TextSize {
pub fn checked_sub(self, rhs: TextSize) -> Option<TextSize> { pub fn checked_sub(self, rhs: TextSize) -> Option<TextSize> {
self.raw.checked_sub(rhs.raw).map(|raw| TextSize { raw }) self.raw.checked_sub(rhs.raw).map(|raw| TextSize { raw })
} }
/// Saturating addition. Returns maximum `TextSize` if overflow occurred.
#[inline]
#[must_use]
pub fn saturating_add(self, rhs: TextSize) -> TextSize {
TextSize {
raw: self.raw.saturating_add(rhs.raw),
}
}
/// Saturating subtraction. Returns minimum `TextSize` if overflow
/// occurred.
#[inline]
#[must_use]
pub fn saturating_sub(self, rhs: TextSize) -> TextSize {
TextSize {
raw: self.raw.saturating_sub(rhs.raw),
}
}
} }
impl From<u32> for TextSize { impl From<u32> for TextSize {

View File

@ -1341,7 +1341,7 @@ fn is_in_definition_place(
/// E.g. naming a parameter, type parameter, or `for` <name>). /// E.g. naming a parameter, type parameter, or `for` <name>).
fn is_in_variable_binding(parsed: &ParsedModuleRef, offset: TextSize, typed: Option<&str>) -> bool { fn is_in_variable_binding(parsed: &ParsedModuleRef, offset: TextSize, typed: Option<&str>) -> bool {
let range = if let Some(typed) = typed { let range = if let Some(typed) = typed {
let start = offset - typed.text_len(); let start = offset.saturating_sub(typed.text_len());
TextRange::new(start, offset) TextRange::new(start, offset)
} else { } else {
TextRange::empty(offset) TextRange::empty(offset)