Avoid byte to char position conversions in is_multiline

Converting a byte position into a char position is currently linear in
the number of multibyte characters in the source code. Avoid it when
checking if a range spans across lines.

This makes it feasible to compile source files with a large number of
multibyte characters.
This commit is contained in:
Tomasz Miąsko 2021-07-01 00:00:00 +00:00
parent f8ac8fdacf
commit 7a410763fa

View file

@ -461,9 +461,13 @@ impl SourceMap {
} }
pub fn is_multiline(&self, sp: Span) -> bool { pub fn is_multiline(&self, sp: Span) -> bool {
let lo = self.lookup_char_pos(sp.lo()); let lo = self.lookup_source_file_idx(sp.lo());
let hi = self.lookup_char_pos(sp.hi()); let hi = self.lookup_source_file_idx(sp.hi());
lo.line != hi.line if lo != hi {
return true;
}
let f = (*self.files.borrow().source_files)[lo].clone();
f.lookup_line(sp.lo()) != f.lookup_line(sp.hi())
} }
pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> { pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> {