From 7a410763facea6aab28cdaeb133179b11a979eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 1 Jul 2021 00:00:00 +0000 Subject: [PATCH] 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. --- compiler/rustc_span/src/source_map.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 32031ac70715..77a3ad931d57 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -461,9 +461,13 @@ impl SourceMap { } pub fn is_multiline(&self, sp: Span) -> bool { - let lo = self.lookup_char_pos(sp.lo()); - let hi = self.lookup_char_pos(sp.hi()); - lo.line != hi.line + let lo = self.lookup_source_file_idx(sp.lo()); + let hi = self.lookup_source_file_idx(sp.hi()); + 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> {