diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index a21d2df41620..c0307263387e 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -191,6 +191,18 @@ fn next_start_pos(&self) -> usize { /// 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 { + 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, OffsetOverflowError> { let start_pos = self.next_start_pos(); // The path is used to determine the directory for loading submodules and @@ -212,7 +224,7 @@ pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc lrc_sf, None => { let source_file = Lrc::new(SourceFile::new( @@ -221,7 +233,7 @@ pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc Lrc Option<&str> { } } +#[derive(Debug)] +pub struct OffsetOverflowError; + /// A single source in the `SourceMap`. #[derive(Clone)] pub struct SourceFile { @@ -1040,7 +1043,7 @@ pub fn new(name: FileName, name_was_remapped: bool, unmapped_path: FileName, mut src: String, - start_pos: BytePos) -> SourceFile { + start_pos: BytePos) -> Result { remove_bom(&mut src); let src_hash = { @@ -1054,11 +1057,14 @@ pub fn new(name: FileName, 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), @@ -1072,7 +1078,7 @@ pub fn new(name: FileName, multibyte_chars, non_narrow_chars, name_hash, - } + }) } /// Returns the `BytePos` of the beginning of the current line.