Merge remote-tracking branch 'origin/trunk' into instantiate-rigids-speedup-again

This commit is contained in:
Folkert 2022-03-05 13:12:55 +01:00
commit 477fe5a48e
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C
2 changed files with 17 additions and 151 deletions

View File

@ -1,133 +0,0 @@
use bumpalo::collections::Vec;
use bumpalo::Bump;
use roc_fmt::def::fmt_def;
use roc_fmt::module::fmt_module;
use roc_parse::ast::{Def, Module};
use roc_parse::module::module_defs;
use roc_parse::parser;
use roc_parse::parser::{Parser, SyntaxError};
use roc_region::all::Located;
use std::ffi::OsStr;
use std::path::Path;
use std::{fs, io};
#[derive(Debug)]
pub struct File<'a> {
path: &'a Path,
module_header: Module<'a>,
content: Vec<'a, Located<Def<'a>>>,
}
#[derive(Debug)]
pub enum ReadError<'a> {
Read(std::io::Error),
ParseDefs(SyntaxError<'a>),
ParseHeader(SyntaxError<'a>),
DoesntHaveRocExtension,
}
impl<'a> File<'a> {
pub fn read(path: &'a Path, arena: &'a Bump) -> Result<File<'a>, ReadError<'a>> {
if path.extension() != Some(OsStr::new("roc")) {
return Err(ReadError::DoesntHaveRocExtension);
}
let bytes = fs::read(path).map_err(ReadError::Read)?;
let allocation = arena.alloc(bytes);
let module_parse_state = parser::State::new(allocation);
let parsed_module = roc_parse::module::parse_header(arena, module_parse_state);
match parsed_module {
Ok((module, state)) => {
let parsed_defs = module_defs().parse(arena, state);
match parsed_defs {
Ok((_, defs, _)) => Ok(File {
path,
module_header: module,
content: defs,
}),
Err((_, error, _)) => Err(ReadError::ParseDefs(error)),
}
}
Err(error) => Err(ReadError::ParseHeader(SyntaxError::Header(error))),
}
}
pub fn fmt(&self) -> String {
let arena = Bump::new();
let mut formatted_file = String::new();
let mut module_header_buf = bumpalo::collections::String::new_in(&arena);
fmt_module(&mut module_header_buf, &self.module_header);
formatted_file.push_str(module_header_buf.as_str());
for def in &self.content {
let mut def_buf = bumpalo::collections::String::new_in(&arena);
fmt_def(&mut def_buf, &def.value, 0);
formatted_file.push_str(def_buf.as_str());
}
formatted_file
}
pub fn fmt_then_write_to(&self, write_path: &'a Path) -> io::Result<()> {
let formatted_file = self.fmt();
fs::write(write_path, formatted_file)
}
pub fn fmt_then_write_with_name(&self, new_name: &str) -> io::Result<()> {
self.fmt_then_write_to(
self.path
.with_file_name(new_name)
.with_extension("roc")
.as_path(),
)
}
pub fn fmt_then_write(&self) -> io::Result<()> {
self.fmt_then_write_to(self.path)
}
}
#[cfg(test)]
mod test_file {
use crate::lang::roc_file;
use bumpalo::Bump;
use std::path::Path;
#[test]
fn read_and_fmt_simple_roc_module() {
let simple_module_path = Path::new("./tests/modules/SimpleUnformatted.roc");
let arena = Bump::new();
let file = roc_file::File::read(simple_module_path, &arena)
.expect("Could not read SimpleUnformatted.roc in test_file test");
assert_eq!(
file.fmt(),
indoc!(
r#"
interface Simple
exposes [
v, x
]
imports []
v : Str
v = "Value!"
x : Int
x = 4"#
)
);
}
}

View File

@ -367,9 +367,9 @@ fn solve(
// then we copy from that module's Subs into our own. If the value
// is being looked up in this module, then we use our Subs as both
// the source and destination.
let actual = deep_copy_var(subs, rank, pools, var);
let actual = deep_copy_var_in(subs, rank, pools, var, arena);
let expectation = &constraints.expectations[expectation_index.index()];
let expected = type_to_var(
subs,
rank,
@ -805,21 +805,16 @@ impl<T> LocalDefVarsVec<T> {
use std::cell::RefCell;
std::thread_local! {
/// Scratchpad arena so we don't need to allocate a new one all the time
static SCRATCHPAD: RefCell<bumpalo::Bump> = RefCell::new(bumpalo::Bump::with_capacity(4 * 1024));
static SCRATCHPAD: RefCell<Option<bumpalo::Bump>> = RefCell::new(Some(bumpalo::Bump::with_capacity(4 * 1024)));
}
fn take_scratchpad() -> bumpalo::Bump {
let mut result = bumpalo::Bump::new();
SCRATCHPAD.with(|f| {
result = f.replace(bumpalo::Bump::new());
});
result
SCRATCHPAD.with(|f| f.take().unwrap())
}
fn put_scratchpad(scratchpad: bumpalo::Bump) {
SCRATCHPAD.with(|f| {
f.replace(scratchpad);
f.replace(Some(scratchpad));
});
}
@ -1002,7 +997,7 @@ fn type_to_variable<'a>(
return reserved;
} else {
// for any other rank, we need to copy; it takes care of adjusting the rank
return deep_copy_var(subs, rank, pools, reserved);
return deep_copy_var_in(subs, rank, pools, reserved, arena);
}
}
@ -1070,6 +1065,7 @@ fn type_to_variable<'a>(
}
}
#[inline(always)]
fn alias_to_var<'a>(
subs: &mut Subs,
rank: Rank,
@ -1099,6 +1095,7 @@ fn alias_to_var<'a>(
}
}
#[inline(always)]
fn roc_result_to_var<'a>(
subs: &mut Subs,
rank: Rank,
@ -1847,10 +1844,14 @@ fn instantiate_rigids_help(subs: &mut Subs, max_rank: Rank, initial: Variable) {
}
}
fn deep_copy_var(subs: &mut Subs, rank: Rank, pools: &mut Pools, var: Variable) -> Variable {
let mut arena = take_scratchpad();
let mut visited = bumpalo::collections::Vec::with_capacity_in(4 * 1024, &arena);
fn deep_copy_var_in(
subs: &mut Subs,
rank: Rank,
pools: &mut Pools,
var: Variable,
arena: &Bump,
) -> Variable {
let mut visited = bumpalo::collections::Vec::with_capacity_in(256, arena);
let copy = deep_copy_var_help(subs, rank, pools, &mut visited, var);
@ -1866,9 +1867,6 @@ fn deep_copy_var(subs: &mut Subs, rank: Rank, pools: &mut Pools, var: Variable)
}
}
arena.reset();
put_scratchpad(arena);
copy
}
@ -2107,6 +2105,7 @@ fn deep_copy_var_help(
}
}
#[inline(always)]
fn register(subs: &mut Subs, rank: Rank, pools: &mut Pools, content: Content) -> Variable {
let descriptor = Descriptor {
content,