Skip to content

Commit fa67f30

Browse files
authored
chore: rename String.ValidPos to String.Pos (#11240)
This PR renames `String.ValidPos` to `String.Pos`, `String.endValidPos` to `String.endPos` and `String.startValidPos` to `String.startPos`. Accordingly, the deprecations of `String.Pos` to `String.Pos.Raw` and `String.endPos` to `String.rawEndPos` are removed early, after an abbreviated deprecation cycle of two releases.
1 parent 6da35ee commit fa67f30

40 files changed

+569
-569
lines changed

script/Shake.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ def parseHeaderFromString (text path : String) :
300300
throw <| .userError "parse errors in file"
301301
-- the insertion point for `add` is the first newline after the imports
302302
let insertion := header.raw.getTailPos?.getD parserState.pos
303-
let insertion := text.findAux (· == '\n') text.endPos insertion + '\n'
303+
let insertion := text.findAux (· == '\n') text.rawEndPos insertion + '\n'
304304
pure (path, inputCtx, header, insertion)
305305

306306
/-- Parse a source file to extract the location of the import lines, for edits and error messages.
@@ -593,16 +593,16 @@ def main (args : List String) : IO UInt32 := do
593593
for stx in imports do
594594
let mod := decodeImport stx
595595
if remove.contains mod || seen.contains mod then
596-
out := out ++ text.extract pos stx.raw.getPos?.get!
596+
out := out ++ String.Pos.Raw.extract text pos stx.raw.getPos?.get!
597597
-- We use the end position of the syntax, but include whitespace up to the first newline
598598
pos := text.findAux (· == '\n') text.rawEndPos stx.raw.getTailPos?.get! + '\n'
599599
seen := seen.insert mod
600-
out := out ++ text.extract pos insertion
600+
out := out ++ String.Pos.Raw.extract text pos insertion
601601
for mod in add do
602602
if !seen.contains mod then
603603
seen := seen.insert mod
604604
out := out ++ s!"{mod}\n"
605-
out := out ++ text.extract insertion text.rawEndPos
605+
out := out ++ String.Pos.Raw.extract text insertion text.rawEndPos
606606

607607
IO.FS.writeFile path out
608608
count := count + 1

src/Init/Data/String/Basic.lean

Lines changed: 199 additions & 204 deletions
Large diffs are not rendered by default.

src/Init/Data/String/Bootstrap.lean

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ public section
1313

1414
namespace String
1515

16-
@[deprecated Pos.Raw (since := "2025-09-30")]
17-
abbrev Pos := Pos.Raw
18-
1916
instance : OfNat String.Pos.Raw (nat_lit 0) where
2017
ofNat := {}
2118

src/Init/Data/String/Defs.lean

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,6 @@ theorem String.bytes_push {s : String} {c : Char} : (s.push c).bytes = s.bytes +
142142

143143
namespace String
144144

145-
@[deprecated rawEndPos (since := "2025-10-20")]
146-
def endPos (s : String) : String.Pos.Raw :=
147-
s.rawEndPos
148-
149145
/-- The start position of the string, as a `String.Pos.Raw.` -/
150146
def rawStartPos (_s : String) : String.Pos.Raw :=
151147
0
@@ -341,55 +337,55 @@ theorem Pos.Raw.isValid_empty_iff {p : Pos.Raw} : p.IsValid "" ↔ p = 0 := by
341337
simp
342338

343339
/--
344-
A `ValidPos s` is a byte offset in `s` together with a proof that this position is at a UTF-8
340+
A `Pos s` is a byte offset in `s` together with a proof that this position is at a UTF-8
345341
character boundary.
346342
-/
347343
@[ext]
348-
structure ValidPos (s : String) where
349-
/-- The underlying byte offset of the `ValidPos`. -/
344+
structure Pos (s : String) where
345+
/-- The underlying byte offset of the `Pos`. -/
350346
offset : Pos.Raw
351347
/-- The proof that `offset` is valid for the string `s`. -/
352348
isValid : offset.IsValid s
353349
deriving @[expose] DecidableEq
354350

355-
/-- The start position of `s`, as an `s.ValidPos`. -/
351+
/-- The start position of `s`, as an `s.Pos`. -/
356352
@[inline, expose]
357-
def startValidPos (s : String) : s.ValidPos where
353+
def startPos (s : String) : s.Pos where
358354
offset := 0
359355
isValid := by simp
360356

361357
@[simp]
362-
theorem offset_startValidPos {s : String} : s.startValidPos.offset = 0 := (rfl)
358+
theorem offset_startPos {s : String} : s.startPos.offset = 0 := (rfl)
363359

364-
instance {s : String} : Inhabited s.ValidPos where
365-
default := s.startValidPos
360+
instance {s : String} : Inhabited s.Pos where
361+
default := s.startPos
366362

367-
/-- The past-the-end position of `s`, as an `s.ValidPos`. -/
363+
/-- The past-the-end position of `s`, as an `s.Pos`. -/
368364
@[inline, expose]
369-
def endValidPos (s : String) : s.ValidPos where
365+
def endPos (s : String) : s.Pos where
370366
offset := s.rawEndPos
371367
isValid := by simp
372368

373369
@[simp]
374-
theorem offset_endValidPos {s : String} : s.endValidPos.offset = s.rawEndPos := (rfl)
370+
theorem offset_endPos {s : String} : s.endPos.offset = s.rawEndPos := (rfl)
375371

376-
instance {s : String} : LE s.ValidPos where
372+
instance {s : String} : LE s.Pos where
377373
le l r := l.offset ≤ r.offset
378374

379-
instance {s : String} : LT s.ValidPos where
375+
instance {s : String} : LT s.Pos where
380376
lt l r := l.offset < r.offset
381377

382-
theorem ValidPos.le_iff {s : String} {l r : s.ValidPos} : l ≤ r ↔ l.offset ≤ r.offset :=
378+
theorem Pos.le_iff {s : String} {l r : s.Pos} : l ≤ r ↔ l.offset ≤ r.offset :=
383379
Iff.rfl
384380

385-
theorem ValidPos.lt_iff {s : String} {l r : s.ValidPos} : l < r ↔ l.offset < r.offset :=
381+
theorem Pos.lt_iff {s : String} {l r : s.Pos} : l < r ↔ l.offset < r.offset :=
386382
Iff.rfl
387383

388-
instance {s : String} (l r : s.ValidPos) : Decidable (l ≤ r) :=
389-
decidable_of_iff' _ ValidPos.le_iff
384+
instance {s : String} (l r : s.Pos) : Decidable (l ≤ r) :=
385+
decidable_of_iff' _ Pos.le_iff
390386

391-
instance {s : String} (l r : s.ValidPos) : Decidable (l < r) :=
392-
decidable_of_iff' _ ValidPos.lt_iff
387+
instance {s : String} (l r : s.Pos) : Decidable (l < r) :=
388+
decidable_of_iff' _ Pos.lt_iff
393389

394390
/--
395391
A region or slice of some underlying string.
@@ -406,30 +402,30 @@ structure Slice where
406402
/-- The underlying strings. -/
407403
str : String
408404
/-- The byte position of the start of the string slice. -/
409-
startInclusive : str.ValidPos
405+
startInclusive : str.Pos
410406
/-- The byte position of the end of the string slice. -/
411-
endExclusive : str.ValidPos
407+
endExclusive : str.Pos
412408
/-- The slice is not degenerate (but it may be empty). -/
413409
startInclusive_le_endExclusive : startInclusive ≤ endExclusive
414410

415411
instance : Inhabited Slice where
416-
default := ⟨"", "".startValidPos, "".startValidPos, by simp [ValidPos.le_iff]⟩
412+
default := ⟨"", "".startPos, "".startPos, by simp [Pos.le_iff]⟩
417413

418414
/--
419415
Returns a slice that contains the entire string.
420416
-/
421417
@[inline, expose] -- expose for the defeq `s.toSlice.str = s`.
422418
def toSlice (s : String) : Slice where
423419
str := s
424-
startInclusive := s.startValidPos
425-
endExclusive := s.endValidPos
426-
startInclusive_le_endExclusive := by simp [ValidPos.le_iff, Pos.Raw.le_iff]
420+
startInclusive := s.startPos
421+
endExclusive := s.endPos
422+
startInclusive_le_endExclusive := by simp [Pos.le_iff, Pos.Raw.le_iff]
427423

428424
@[simp]
429-
theorem startInclusive_toSlice {s : String} : s.toSlice.startInclusive = s.startValidPos := rfl
425+
theorem startInclusive_toSlice {s : String} : s.toSlice.startInclusive = s.startPos := rfl
430426

431427
@[simp]
432-
theorem endExclusive_toSlice {s : String} : s.toSlice.endExclusive = s.endValidPos := rfl
428+
theorem endExclusive_toSlice {s : String} : s.toSlice.endExclusive = s.endPos := rfl
433429

434430
@[simp]
435431
theorem str_toSlice {s : String} : s.toSlice.str = s := rfl
@@ -532,7 +528,7 @@ instance {s : Slice} : Inhabited s.Pos where
532528
theorem Slice.offset_startInclusive_add_self {s : Slice} :
533529
s.startInclusive.offset + s = s.endExclusive.offset := by
534530
have := s.startInclusive_le_endExclusive
535-
simp_all [String.Pos.Raw.ext_iff, ValidPos.le_iff, Pos.Raw.le_iff, utf8ByteSize_eq]
531+
simp_all [String.Pos.Raw.ext_iff, Pos.le_iff, Pos.Raw.le_iff, utf8ByteSize_eq]
536532

537533
@[simp]
538534
theorem Pos.Raw.offsetBy_rawEndPos_left {p : Pos.Raw} {s : String} :
@@ -591,18 +587,18 @@ instance {s : Slice} (l r : s.Pos) : Decidable (l < r) :=
591587
decidable_of_iff' _ Slice.Pos.lt_iff
592588

593589
/--
594-
`pos.IsAtEnd` is just shorthand for `pos = s.endValidPos` that is easier to write if `s` is long.
590+
`pos.IsAtEnd` is just shorthand for `pos = s.endPos` that is easier to write if `s` is long.
595591
-/
596-
abbrev ValidPos.IsAtEnd {s : String} (pos : s.ValidPos) : Prop :=
597-
pos = s.endValidPos
592+
abbrev Pos.IsAtEnd {s : String} (pos : s.Pos) : Prop :=
593+
pos = s.endPos
598594

599595
@[simp]
600-
theorem ValidPos.isAtEnd_iff {s : String} {pos : s.ValidPos} :
601-
pos.IsAtEnd ↔ pos = s.endValidPos := Iff.rfl
596+
theorem Pos.isAtEnd_iff {s : String} {pos : s.Pos} :
597+
pos.IsAtEnd ↔ pos = s.endPos := Iff.rfl
602598

603599
@[inline]
604-
instance {s : String} {pos : s.ValidPos} : Decidable pos.IsAtEnd :=
605-
decidable_of_iff _ ValidPos.isAtEnd_iff
600+
instance {s : String} {pos : s.Pos} : Decidable pos.IsAtEnd :=
601+
decidable_of_iff _ Pos.isAtEnd_iff
606602

607603
/--
608604
`pos.IsAtEnd` is just shorthand for `pos = s.endPos` that is easier to write if `s` is long.
@@ -639,4 +635,16 @@ def toSubstring (s : String) : Substring.Raw :=
639635
def toSubstring' (s : String) : Substring.Raw :=
640636
s.toRawSubstring'
641637

638+
@[deprecated String.Pos (since := "2025-11-24")]
639+
abbrev ValidPos (s : String) : Type :=
640+
s.Pos
641+
642+
@[deprecated String.startPos (since := "2025-11-24")]
643+
abbrev startValidPos (s : String) : s.Pos :=
644+
s.startPos
645+
646+
@[deprecated String.endPos (since := "2025-11-24")]
647+
abbrev endValidPos (s : String) : s.Pos :=
648+
s.endPos
649+
642650
end String

src/Init/Data/String/Extra.lean

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,36 @@ abbrev validateUTF8 (a : ByteArray) : Bool :=
2929
a.validateUTF8
3030

3131
private def findLeadingSpacesSize (s : String) : Nat :=
32-
let it := s.startValidPos
33-
let it := it.find? (· == '\n') |>.bind String.ValidPos.next?
32+
let it := s.startPos
33+
let it := it.find? (· == '\n') |>.bind String.Pos.next?
3434
match it with
3535
| some it => consumeSpaces it 0 s.length
3636
| none => 0
3737
where
38-
consumeSpaces {s : String} (it : s.ValidPos) (curr min : Nat) : Nat :=
38+
consumeSpaces {s : String} (it : s.Pos) (curr min : Nat) : Nat :=
3939
if h : it.IsAtEnd then min
4040
else if it.get h == ' ' || it.get h == '\t' then consumeSpaces (it.next h) (curr + 1) min
4141
else if it.get h == '\n' then findNextLine (it.next h) min
4242
else findNextLine (it.next h) (Nat.min curr min)
4343
termination_by it
44-
findNextLine {s : String} (it : s.ValidPos) (min : Nat) : Nat :=
44+
findNextLine {s : String} (it : s.Pos) (min : Nat) : Nat :=
4545
if h : it.IsAtEnd then min
4646
else if it.get h == '\n' then consumeSpaces (it.next h) 0 min
4747
else findNextLine (it.next h) min
4848
termination_by it
4949

5050
private def removeNumLeadingSpaces (n : Nat) (s : String) : String :=
51-
consumeSpaces n s.startValidPos ""
51+
consumeSpaces n s.startPos ""
5252
where
53-
consumeSpaces (n : Nat) {s : String} (it : s.ValidPos) (r : String) : String :=
53+
consumeSpaces (n : Nat) {s : String} (it : s.Pos) (r : String) : String :=
5454
match n with
5555
| 0 => saveLine it r
5656
| n+1 =>
5757
if h : it.IsAtEnd then r
5858
else if it.get h == ' ' || it.get h == '\t' then consumeSpaces n (it.next h) r
5959
else saveLine it r
6060
termination_by (it, 1)
61-
saveLine {s : String} (it : s.ValidPos) (r : String) : String :=
61+
saveLine {s : String} (it : s.Pos) (r : String) : String :=
6262
if h : it.IsAtEnd then r
6363
else if it.get h == '\n' then consumeSpaces n (it.next h) (r.push '\n')
6464
else saveLine (it.next h) (r.push (it.get h))

src/Init/Data/String/Iterator.lean

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ An iterator over the characters (Unicode code points) in a `String`. Typically c
2525
`String.iter`.
2626
2727
This is a no-longer-supported legacy API that will be removed in a future release. You should use
28-
`String.ValidPos` instead, which is similar, but safer. To iterate over a string `s`, start with
29-
`p : s.startValidPos`, advance it using `p.next`, access the current character using `p.get` and
30-
check if the position is at the end using `p = s.endValidPos` or `p.IsAtEnd`.
28+
`String.Pos` instead, which is similar, but safer. To iterate over a string `s`, start with
29+
`p : s.startPos`, advance it using `p.next`, access the current character using `p.get` and
30+
check if the position is at the end using `p = s.endPos` or `p.IsAtEnd`.
3131
3232
String iterators pair a string with a valid byte index. This allows efficient character-by-character
3333
processing of strings while avoiding the need to manually ensure that byte indices are used with the
@@ -57,9 +57,9 @@ structure Iterator where
5757
/-- Creates an iterator at the beginning of the string.
5858
5959
This is a no-longer-supported legacy API that will be removed in a future release. You should use
60-
`String.ValidPos` instead, which is similar, but safer. To iterate over a string `s`, start with
61-
`p : s.startValidPos`, advance it using `p.next`, access the current character using `p.get` and
62-
check if the position is at the end using `p = s.endValidPos` or `p.IsAtEnd`.
60+
`String.Pos` instead, which is similar, but safer. To iterate over a string `s`, start with
61+
`p : s.startPos`, advance it using `p.next`, access the current character using `p.get` and
62+
check if the position is at the end using `p = s.endPos` or `p.IsAtEnd`.
6363
-/
6464
@[inline] def mkIterator (s : String) : Iterator :=
6565
⟨s, 0
@@ -95,9 +95,9 @@ def pos := Iterator.i
9595
Gets the character at the iterator's current position.
9696
9797
This is a no-longer-supported legacy API that will be removed in a future release. You should use
98-
`String.ValidPos` instead, which is similar, but safer. To iterate over a string `s`, start with
99-
`p : s.startValidPos`, advance it using `p.next`, access the current character using `p.get` and
100-
check if the position is at the end using `p = s.endValidPos` or `p.IsAtEnd`.
98+
`String.Pos` instead, which is similar, but safer. To iterate over a string `s`, start with
99+
`p : s.startPos`, advance it using `p.next`, access the current character using `p.get` and
100+
check if the position is at the end using `p = s.endPos` or `p.IsAtEnd`.
101101
102102
A run-time bounds check is performed. Use `String.Iterator.curr'` to avoid redundant bounds checks.
103103
@@ -110,9 +110,9 @@ If the position is invalid, returns `(default : Char)`.
110110
Moves the iterator's position forward by one character, unconditionally.
111111
112112
This is a no-longer-supported legacy API that will be removed in a future release. You should use
113-
`String.ValidPos` instead, which is similar, but safer. To iterate over a string `s`, start with
114-
`p : s.startValidPos`, advance it using `p.next`, access the current character using `p.get` and
115-
check if the position is at the end using `p = s.endValidPos` or `p.IsAtEnd`.
113+
`String.Pos` instead, which is similar, but safer. To iterate over a string `s`, start with
114+
`p : s.startPos`, advance it using `p.next`, access the current character using `p.get` and
115+
check if the position is at the end using `p = s.endPos` or `p.IsAtEnd`.
116116
117117
It is only valid to call this function if the iterator is not at the end of the string (i.e.
118118
if `Iterator.atEnd` is `false`); otherwise, the resulting iterator will be invalid.

src/Init/Data/String/Lemmas/Basic.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ theorem singleton_ne_empty {c : Char} : singleton c ≠ "" := by
4141

4242
@[simp]
4343
theorem Slice.Pos.toCopy_inj {s : Slice} {p₁ p₂ : s.Pos} : p₁.toCopy = p₂.toCopy ↔ p₁ = p₂ := by
44-
simp [Pos.ext_iff, ValidPos.ext_iff]
44+
simp [String.Pos.ext_iff, Pos.ext_iff]
4545

4646
@[simp]
47-
theorem ValidPos.startValidPos_le {s : String} (p : s.ValidPos) : s.startValidPos ≤ p := by
48-
simp [ValidPos.le_iff, Pos.Raw.le_iff]
47+
theorem Pos.startPos_le {s : String} (p : s.Pos) : s.startPos ≤ p := by
48+
simp [Pos.le_iff, Pos.Raw.le_iff]
4949

5050
@[simp]
5151
theorem Slice.Pos.startPos_le {s : Slice} (p : s.Pos) : s.startPos ≤ p := by

src/Init/Data/String/Lemmas/Modify.lean

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,22 @@ public section
2222

2323
namespace String
2424

25-
/-- You might want to invoke `ValidPos.Splits.exists_eq_singleton_append` to be able to apply this. -/
26-
theorem ValidPos.Splits.pastSet {s : String} {p : s.ValidPos} {t₁ t₂ : String}
25+
/-- You might want to invoke `Pos.Splits.exists_eq_singleton_append` to be able to apply this. -/
26+
theorem Pos.Splits.pastSet {s : String} {p : s.Pos} {t₁ t₂ : String}
2727
{c d : Char} (h : p.Splits t₁ (singleton c ++ t₂)) :
28-
(p.pastSet d h.ne_endValidPos_of_singleton).Splits (t₁ ++ singleton d) t₂ := by
29-
generalize h.ne_endValidPos_of_singleton = hp
28+
(p.pastSet d h.ne_endPos_of_singleton).Splits (t₁ ++ singleton d) t₂ := by
29+
generalize h.ne_endPos_of_singleton = hp
3030
obtain ⟨rfl, rfl, rfl⟩ := by simpa using h.eq (p.splits_next_right hp)
3131
apply splits_pastSet
3232

33-
/-- You might want to invoke `ValidPos.Splits.exists_eq_singleton_append` to be able to apply this. -/
34-
theorem ValidPos.Splits.pastModify {s : String} {p : s.ValidPos} {t₁ t₂ : String}
33+
/-- You might want to invoke `Pos.Splits.exists_eq_singleton_append` to be able to apply this. -/
34+
theorem Pos.Splits.pastModify {s : String} {p : s.Pos} {t₁ t₂ : String}
3535
{c : Char} (h : p.Splits t₁ (singleton c ++ t₂)) :
36-
(p.pastModify f h.ne_endValidPos_of_singleton).Splits
37-
(t₁ ++ singleton (f (p.get h.ne_endValidPos_of_singleton))) t₂ :=
36+
(p.pastModify f h.ne_endPos_of_singleton).Splits
37+
(t₁ ++ singleton (f (p.get h.ne_endPos_of_singleton))) t₂ :=
3838
h.pastSet
3939

40-
theorem toList_mapAux {f : Char → Char} {s : String} {p : s.ValidPos}
40+
theorem toList_mapAux {f : Char → Char} {s : String} {p : s.Pos}
4141
(h : p.Splits t₁ t₂) : (mapAux f s p).toList = t₁.toList ++ t₂.toList.map f := by
4242
fun_induction mapAux generalizing t₁ t₂ with
4343
| case1 s => simp_all
@@ -47,7 +47,7 @@ theorem toList_mapAux {f : Char → Char} {s : String} {p : s.ValidPos}
4747

4848
@[simp]
4949
theorem toList_map {f : Char → Char} {s : String} : (s.map f).toList = s.toList.map f := by
50-
simp [map, toList_mapAux s.splits_startValidPos]
50+
simp [map, toList_mapAux s.splits_startPos]
5151

5252
@[simp]
5353
theorem length_map {f : Char → Char} {s : String} : (s.map f).length = s.length := by

0 commit comments

Comments
 (0)