Skip to content

Commit 47dad31

Browse files
committed
rustc_span: represent line bounds with Range
1 parent df59a44 commit 47dad31

File tree

2 files changed

+24
-30
lines changed

2 files changed

+24
-30
lines changed

compiler/rustc_span/src/caching_source_map_view.rs

+19-25
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
use crate::source_map::SourceMap;
22
use crate::{BytePos, SourceFile};
33
use rustc_data_structures::sync::Lrc;
4+
use std::ops::Range;
45

56
#[derive(Clone)]
67
struct CacheEntry {
78
time_stamp: usize,
89
line_number: usize,
9-
line_start: BytePos,
10-
line_end: BytePos,
10+
// The line's byte position range in the `SourceMap`. This range will fail to contain a valid
11+
// position in certain edge cases. Spans often start/end one past something, and when that
12+
// something is the last character of a file (this can happen when a file doesn't end in a
13+
// newline, for example), we'd still like for the position to be considered within the last
14+
// line. However, it isn't according to the exclusive upper bound of this range. We cannot
15+
// change the upper bound to be inclusive, because for most lines, the upper bound is the same
16+
// as the lower bound of the next line, so there would be an ambiguity.
17+
//
18+
// Since the containment aspect of this range is only used to see whether or not the cache
19+
// entry contains a position, the only ramification of the above is that we will get cache
20+
// misses for these rare positions. A line lookup for the position via `SourceMap::lookup_line`
21+
// after a cache miss will produce the last line number, as desired.
22+
line: Range<BytePos>,
1123
file: Lrc<SourceFile>,
1224
file_index: usize,
1325
}
@@ -26,8 +38,7 @@ impl<'sm> CachingSourceMapView<'sm> {
2638
let entry = CacheEntry {
2739
time_stamp: 0,
2840
line_number: 0,
29-
line_start: BytePos(0),
30-
line_end: BytePos(0),
41+
line: BytePos(0)..BytePos(0),
3142
file: first_file,
3243
file_index: 0,
3344
};
@@ -47,13 +58,13 @@ impl<'sm> CachingSourceMapView<'sm> {
4758

4859
// Check if the position is in one of the cached lines
4960
for cache_entry in self.line_cache.iter_mut() {
50-
if line_contains((cache_entry.line_start, cache_entry.line_end), pos) {
61+
if cache_entry.line.contains(&pos) {
5162
cache_entry.time_stamp = self.time_stamp;
5263

5364
return Some((
5465
cache_entry.file.clone(),
5566
cache_entry.line_number,
56-
pos - cache_entry.line_start,
67+
pos - cache_entry.line.start,
5768
));
5869
}
5970
}
@@ -95,30 +106,13 @@ impl<'sm> CachingSourceMapView<'sm> {
95106
let line_bounds = cache_entry.file.line_bounds(line_index);
96107

97108
cache_entry.line_number = line_index + 1;
98-
cache_entry.line_start = line_bounds.0;
99-
cache_entry.line_end = line_bounds.1;
109+
cache_entry.line = line_bounds;
100110
cache_entry.time_stamp = self.time_stamp;
101111

102-
Some((cache_entry.file.clone(), cache_entry.line_number, pos - cache_entry.line_start))
112+
Some((cache_entry.file.clone(), cache_entry.line_number, pos - cache_entry.line.start))
103113
}
104114
}
105115

106-
#[inline]
107-
fn line_contains(line_bounds: (BytePos, BytePos), pos: BytePos) -> bool {
108-
// This condition will be false in one case where we'd rather it wasn't. Spans often start/end
109-
// one past something, and when that something is the last character of a file (this can happen
110-
// when a file doesn't end in a newline, for example), we'd still like for the position to be
111-
// considered within the last line. However, it isn't according to the exclusive upper bound
112-
// below. We cannot change the upper bound to be inclusive, because for most lines, the upper
113-
// bound is the same as the lower bound of the next line, so there would be an ambiguity.
114-
//
115-
// Supposing we only use this function to check whether or not the line cache entry contains
116-
// a position, the only ramification of the above is that we will get cache misses for these
117-
// rare positions. A line lookup for the position via `SourceMap::lookup_line` after a cache
118-
// miss will produce the last line number, as desired.
119-
line_bounds.0 <= pos && pos < line_bounds.1
120-
}
121-
122116
#[inline]
123117
fn file_contains(file: &SourceFile, pos: BytePos) -> bool {
124118
// `SourceMap::lookup_source_file_idx` and `SourceFile::contains` both consider the position

compiler/rustc_span/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use std::cell::RefCell;
5252
use std::cmp::{self, Ordering};
5353
use std::fmt;
5454
use std::hash::Hash;
55-
use std::ops::{Add, Sub};
55+
use std::ops::{Add, Range, Sub};
5656
use std::path::{Path, PathBuf};
5757
use std::str::FromStr;
5858

@@ -1426,16 +1426,16 @@ impl SourceFile {
14261426
if line_index >= 0 { Some(line_index as usize) } else { None }
14271427
}
14281428

1429-
pub fn line_bounds(&self, line_index: usize) -> (BytePos, BytePos) {
1429+
pub fn line_bounds(&self, line_index: usize) -> Range<BytePos> {
14301430
if self.is_empty() {
1431-
return (self.start_pos, self.end_pos);
1431+
return self.start_pos..self.end_pos;
14321432
}
14331433

14341434
assert!(line_index < self.lines.len());
14351435
if line_index == (self.lines.len() - 1) {
1436-
(self.lines[line_index], self.end_pos)
1436+
self.lines[line_index]..self.end_pos
14371437
} else {
1438-
(self.lines[line_index], self.lines[line_index + 1])
1438+
self.lines[line_index]..self.lines[line_index + 1]
14391439
}
14401440
}
14411441

0 commit comments

Comments
 (0)