don't ICE on large files
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.
This commit is contained in:
parent
70456a6cbd
commit
ccb2dfbfec
2 changed files with 25 additions and 6 deletions
|
@ -191,6 +191,18 @@ impl SourceMap {
|
||||||
/// If a file already exists in the source_map with the same id, that file is returned
|
/// If a file already exists in the source_map with the same id, that file is returned
|
||||||
/// unmodified
|
/// unmodified
|
||||||
pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc<SourceFile> {
|
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();
|
let start_pos = self.next_start_pos();
|
||||||
|
|
||||||
// The path is used to determine the directory for loading submodules and
|
// The path is used to determine the directory for loading submodules and
|
||||||
|
@ -212,7 +224,7 @@ impl SourceMap {
|
||||||
was_remapped,
|
was_remapped,
|
||||||
Some(&unmapped_path));
|
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,
|
Some(lrc_sf) => lrc_sf,
|
||||||
None => {
|
None => {
|
||||||
let source_file = Lrc::new(SourceFile::new(
|
let source_file = Lrc::new(SourceFile::new(
|
||||||
|
@ -221,7 +233,7 @@ impl SourceMap {
|
||||||
unmapped_path,
|
unmapped_path,
|
||||||
src,
|
src,
|
||||||
Pos::from_usize(start_pos),
|
Pos::from_usize(start_pos),
|
||||||
));
|
)?);
|
||||||
|
|
||||||
let mut files = self.files.borrow_mut();
|
let mut files = self.files.borrow_mut();
|
||||||
|
|
||||||
|
@ -230,7 +242,8 @@ impl SourceMap {
|
||||||
|
|
||||||
source_file
|
source_file
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
Ok(lrc_sf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a new SourceFile representing a source file from an external
|
/// Allocates a new SourceFile representing a source file from an external
|
||||||
|
|
|
@ -859,6 +859,9 @@ impl ExternalSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct OffsetOverflowError;
|
||||||
|
|
||||||
/// A single source in the `SourceMap`.
|
/// A single source in the `SourceMap`.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SourceFile {
|
pub struct SourceFile {
|
||||||
|
@ -1040,7 +1043,7 @@ impl SourceFile {
|
||||||
name_was_remapped: bool,
|
name_was_remapped: bool,
|
||||||
unmapped_path: FileName,
|
unmapped_path: FileName,
|
||||||
mut src: String,
|
mut src: String,
|
||||||
start_pos: BytePos) -> SourceFile {
|
start_pos: BytePos) -> Result<SourceFile, OffsetOverflowError> {
|
||||||
remove_bom(&mut src);
|
remove_bom(&mut src);
|
||||||
|
|
||||||
let src_hash = {
|
let src_hash = {
|
||||||
|
@ -1054,11 +1057,14 @@ impl SourceFile {
|
||||||
hasher.finish()
|
hasher.finish()
|
||||||
};
|
};
|
||||||
let end_pos = start_pos.to_usize() + src.len();
|
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) =
|
let (lines, multibyte_chars, non_narrow_chars) =
|
||||||
analyze_source_file::analyze_source_file(&src[..], start_pos);
|
analyze_source_file::analyze_source_file(&src[..], start_pos);
|
||||||
|
|
||||||
SourceFile {
|
Ok(SourceFile {
|
||||||
name,
|
name,
|
||||||
name_was_remapped,
|
name_was_remapped,
|
||||||
unmapped_path: Some(unmapped_path),
|
unmapped_path: Some(unmapped_path),
|
||||||
|
@ -1072,7 +1078,7 @@ impl SourceFile {
|
||||||
multibyte_chars,
|
multibyte_chars,
|
||||||
non_narrow_chars,
|
non_narrow_chars,
|
||||||
name_hash,
|
name_hash,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the `BytePos` of the beginning of the current line.
|
/// Returns the `BytePos` of the beginning of the current line.
|
||||||
|
|
Loading…
Reference in a new issue