Skip to content

Commit

Permalink
don't ICE on large files
Browse files Browse the repository at this point in the history
This is an extremely marginal error, so the cost of properly threading
`Handler` everywhere just not seemed justified. However, it's useful
to panic when we create a file, and not when we slice strings with
overflown indexes somewhere in the guts of the compiler.

For this reason, while we provide safe `try_new_source_file`, we don't
change the existing public interface and just panic more or less
cleanly.
  • Loading branch information
matklad committed Jun 17, 2019
1 parent 70456a6 commit ccb2dfb
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
19 changes: 16 additions & 3 deletions src/libsyntax/source_map.rs
Expand Up @@ -191,6 +191,18 @@ impl SourceMap {
/// If a file already exists in the source_map with the same id, that file is returned
/// unmodified
pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc<SourceFile> {
self.try_new_source_file(filename, src)
.unwrap_or_else(|OffsetOverflowError| {
eprintln!("fatal error: rustc does not support files larger than 4GB");
errors::FatalError.raise()
})
}

fn try_new_source_file(
&self,
filename: FileName,
src: String
) -> Result<Lrc<SourceFile>, OffsetOverflowError> {
let start_pos = self.next_start_pos();

// The path is used to determine the directory for loading submodules and
Expand All @@ -212,7 +224,7 @@ impl SourceMap {
was_remapped,
Some(&unmapped_path));

return match self.source_file_by_stable_id(file_id) {
let lrc_sf = match self.source_file_by_stable_id(file_id) {
Some(lrc_sf) => lrc_sf,
None => {
let source_file = Lrc::new(SourceFile::new(
Expand All @@ -221,7 +233,7 @@ impl SourceMap {
unmapped_path,
src,
Pos::from_usize(start_pos),
));
)?);

let mut files = self.files.borrow_mut();

Expand All @@ -230,7 +242,8 @@ impl SourceMap {

source_file
}
}
};
Ok(lrc_sf)
}

/// Allocates a new SourceFile representing a source file from an external
Expand Down
12 changes: 9 additions & 3 deletions src/libsyntax_pos/lib.rs
Expand Up @@ -859,6 +859,9 @@ impl ExternalSource {
}
}

#[derive(Debug)]
pub struct OffsetOverflowError;

/// A single source in the `SourceMap`.
#[derive(Clone)]
pub struct SourceFile {
Expand Down Expand Up @@ -1040,7 +1043,7 @@ impl SourceFile {
name_was_remapped: bool,
unmapped_path: FileName,
mut src: String,
start_pos: BytePos) -> SourceFile {
start_pos: BytePos) -> Result<SourceFile, OffsetOverflowError> {
remove_bom(&mut src);

let src_hash = {
Expand All @@ -1054,11 +1057,14 @@ impl SourceFile {
hasher.finish()
};
let end_pos = start_pos.to_usize() + src.len();
if end_pos > u32::max_value() as usize {
return Err(OffsetOverflowError);
}

let (lines, multibyte_chars, non_narrow_chars) =
analyze_source_file::analyze_source_file(&src[..], start_pos);

SourceFile {
Ok(SourceFile {
name,
name_was_remapped,
unmapped_path: Some(unmapped_path),
Expand All @@ -1072,7 +1078,7 @@ impl SourceFile {
multibyte_chars,
non_narrow_chars,
name_hash,
}
})
}

/// Returns the `BytePos` of the beginning of the current line.
Expand Down

0 comments on commit ccb2dfb

Please sign in to comment.