Skip to content

Wrong line numbers produces in rustc_span::SourceFile::lookup_file_pos* #84127

Open
@klensy

Description

@klensy

Function comments noted, that they returns 1-based line number, but can actually return 0-based, #77080 @richkadel

/// Looks up the file's (1-based) line number and (0-based `CharPos`) column offset, for a
/// given `BytePos`.
pub fn lookup_file_pos(&self, pos: BytePos) -> (usize, CharPos) {
let chpos = self.bytepos_to_file_charpos(pos);
match self.lookup_line(pos) {
Some(a) => {
let line = a + 1; // Line numbers start at 1
let linebpos = self.lines[a];
let linechpos = self.bytepos_to_file_charpos(linebpos);
let col = chpos - linechpos;
debug!("byte pos {:?} is on the line at byte pos {:?}", pos, linebpos);
debug!("char pos {:?} is on the line at char pos {:?}", chpos, linechpos);
debug!("byte is on line: {}", line);
assert!(chpos >= linechpos);
(line, col)
}
None => (0, chpos),
}
}
/// Looks up the file's (1-based) line number, (0-based `CharPos`) column offset, and (0-based)
/// column offset when displayed, for a given `BytePos`.
pub fn lookup_file_pos_with_col_display(&self, pos: BytePos) -> (usize, CharPos, usize) {
let (line, col_or_chpos) = self.lookup_file_pos(pos);
if line > 0 {
let col = col_or_chpos;
let linebpos = self.lines[line - 1];
let col_display = {
let start_width_idx = self
.non_narrow_chars
.binary_search_by_key(&linebpos, |x| x.pos())
.unwrap_or_else(|x| x);
let end_width_idx = self
.non_narrow_chars
.binary_search_by_key(&pos, |x| x.pos())
.unwrap_or_else(|x| x);
let special_chars = end_width_idx - start_width_idx;
let non_narrow: usize = self.non_narrow_chars[start_width_idx..end_width_idx]
.iter()
.map(|x| x.width())
.sum();
col.0 - special_chars + non_narrow
};
(line, col, col_display)
} else {
let chpos = col_or_chpos;
let col_display = {
let end_width_idx = self
.non_narrow_chars
.binary_search_by_key(&pos, |x| x.pos())
.unwrap_or_else(|x| x);
let non_narrow: usize =
self.non_narrow_chars[0..end_width_idx].iter().map(|x| x.width()).sum();
chpos.0 - end_width_idx + non_narrow
};
(0, chpos, col_display)
}
}
}

Perhaps this can be prevented via using different types for 0- and 1- based line numbers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions