/// 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
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(
unmapped_path,
src,
Pos::from_usize(start_pos),
- ));
+ )?);
let mut files = self.files.borrow_mut();
source_file
}
- }
+ };
+ Ok(lrc_sf)
}
/// Allocates a new SourceFile representing a source file from an external
}
}
+#[derive(Debug)]
+pub struct OffsetOverflowError;
+
/// A single source in the `SourceMap`.
#[derive(Clone)]
pub struct 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 = {
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),
multibyte_chars,
non_narrow_chars,
name_hash,
- }
+ })
}
/// Returns the `BytePos` of the beginning of the current line.