Merge pull request #3697 from rtfeldman/test-interfaces

Allow `roc test` on interface modules
This commit is contained in:
Folkert de Vries 2022-08-05 00:01:38 +02:00 committed by GitHub
commit 801f692067
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 329 additions and 246 deletions

View file

@ -1,20 +1,21 @@
use bumpalo::Bump;
use roc_load::{LoadedModule, Threading};
use roc_load::{ExecutionMode, LoadConfig, LoadedModule, Threading};
use roc_target::TargetInfo;
use std::path::Path;
pub fn load_module(src_file: &Path, threading: Threading) -> LoadedModule {
let subs_by_module = Default::default();
let arena = Bump::new();
let loaded = roc_load::load_and_typecheck(
&arena,
src_file.to_path_buf(),
subs_by_module,
TargetInfo::default_x86_64(),
roc_reporting::report::RenderTarget::ColorTerminal,
let load_config = LoadConfig {
target_info: TargetInfo::default_x86_64(), // editor only needs type info, so this is unused
render: roc_reporting::report::RenderTarget::ColorTerminal,
threading,
);
exec_mode: ExecutionMode::Check,
};
let arena = Bump::new();
let loaded =
roc_load::load_and_typecheck(&arena, src_file.to_path_buf(), subs_by_module, load_config);
match loaded {
Ok(x) => x,

View file

@ -5,7 +5,7 @@ use roc_build::{
};
use roc_builtins::bitcode;
use roc_collections::VecMap;
use roc_load::{Expectations, LoadingProblem, Threading};
use roc_load::{EntryPoint, ExecutionMode, Expectations, LoadConfig, LoadingProblem, Threading};
use roc_module::symbol::{Interns, ModuleId};
use roc_mono::ir::OptLevel;
use roc_reporting::report::RenderTarget;
@ -55,14 +55,18 @@ pub fn build_file<'a>(
// Step 1: compile the app and generate the .o file
let subs_by_module = Default::default();
let load_config = LoadConfig {
target_info,
// TODO: expose this from CLI?
render: RenderTarget::ColorTerminal,
threading,
exec_mode: ExecutionMode::Executable,
};
let loaded = roc_load::load_and_monomorphize(
arena,
app_module_path.clone(),
subs_by_module,
target_info,
// TODO: expose this from CLI?
RenderTarget::ColorTerminal,
threading,
load_config,
)?;
use target_lexicon::Architecture;
@ -97,10 +101,14 @@ pub fn build_file<'a>(
binary_path.set_extension(extension);
}
let host_input_path = cwd
.join(&*loaded.platform_path)
.with_file_name("host")
.with_extension(host_extension);
let host_input_path = if let EntryPoint::Executable { platform_path, .. } = &loaded.entry_point
{
cwd.join(platform_path)
.with_file_name("host")
.with_extension(host_extension)
} else {
unreachable!();
};
// TODO this should probably be moved before load_and_monomorphize.
// To do this we will need to preprocess files just for their exported symbols.
@ -438,15 +446,15 @@ pub fn check_file(
// Step 1: compile the app and generate the .o file
let subs_by_module = Default::default();
let mut loaded = roc_load::load_and_typecheck(
arena,
roc_file_path,
subs_by_module,
let load_config = LoadConfig {
target_info,
// TODO: expose this from CLI?
RenderTarget::ColorTerminal,
render: RenderTarget::ColorTerminal,
threading,
)?;
exec_mode: ExecutionMode::Check,
};
let mut loaded =
roc_load::load_and_typecheck(arena, roc_file_path, subs_by_module, load_config)?;
let buf = &mut String::with_capacity(1024);

View file

@ -10,7 +10,7 @@ use roc_error_macros::{internal_error, user_error};
use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_gen_llvm::run_roc::RocCallResult;
use roc_gen_llvm::run_roc_dylib;
use roc_load::{Expectations, LoadingProblem, Threading};
use roc_load::{ExecutionMode, Expectations, LoadConfig, LoadingProblem, Threading};
use roc_module::symbol::{Interns, ModuleId};
use roc_mono::ir::OptLevel;
use roc_repl_expect::run::{expect_mono_module_to_dylib, roc_dev_expect};
@ -361,16 +361,16 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
// Step 1: compile the app and generate the .o file
let subs_by_module = Default::default();
let loaded = roc_load::load_and_monomorphize(
arena,
path.to_path_buf(),
subs_by_module,
let load_config = LoadConfig {
target_info,
// TODO: expose this from CLI?
roc_reporting::report::RenderTarget::ColorTerminal,
render: roc_reporting::report::RenderTarget::ColorTerminal,
threading,
)
.unwrap();
exec_mode: ExecutionMode::Test,
};
let loaded =
roc_load::load_and_monomorphize(arena, path.to_path_buf(), subs_by_module, load_config)
.unwrap();
let mut loaded = loaded;
let mut expectations = std::mem::take(&mut loaded.expectations);

View file

@ -131,7 +131,7 @@ fn bytes_as_ascii(bytes: &[u8]) -> String {
pub fn spec_program<'a, I>(
opt_level: OptLevel,
entry_point: roc_mono::ir::EntryPoint<'a>,
opt_entry_point: Option<roc_mono::ir::EntryPoint<'a>>,
procs: I,
) -> Result<morphic_lib::Solutions>
where
@ -221,19 +221,21 @@ where
m.add_func(func_name, spec)?;
}
// the entry point wrapper
let roc_main_bytes = func_name_bytes_help(
entry_point.symbol,
entry_point.layout.arguments.iter().copied(),
CapturesNiche::no_niche(),
&entry_point.layout.result,
);
let roc_main = FuncName(&roc_main_bytes);
if let Some(entry_point) = opt_entry_point {
// the entry point wrapper
let roc_main_bytes = func_name_bytes_help(
entry_point.symbol,
entry_point.layout.arguments.iter().copied(),
CapturesNiche::no_niche(),
&entry_point.layout.result,
);
let roc_main = FuncName(&roc_main_bytes);
let entry_point_function =
build_entry_point(entry_point.layout, roc_main, &host_exposed_functions)?;
let entry_point_name = FuncName(ENTRY_POINT_NAME);
m.add_func(entry_point_name, entry_point_function)?;
let entry_point_function =
build_entry_point(entry_point.layout, roc_main, &host_exposed_functions)?;
let entry_point_name = FuncName(ENTRY_POINT_NAME);
m.add_func(entry_point_name, entry_point_function)?;
}
for union_layout in type_definitions {
let type_name_bytes = recursive_tag_union_name_bytes(&union_layout).as_bytes();
@ -264,8 +266,10 @@ where
let mut p = ProgramBuilder::new();
p.add_mod(MOD_APP, main_module)?;
let entry_point_name = FuncName(ENTRY_POINT_NAME);
p.add_entry_point(EntryPointName(ENTRY_POINT_NAME), MOD_APP, entry_point_name)?;
if opt_entry_point.is_some() {
let entry_point_name = FuncName(ENTRY_POINT_NAME);
p.add_entry_point(EntryPointName(ENTRY_POINT_NAME), MOD_APP, entry_point_name)?;
}
p.build()?
};

View file

@ -1,7 +1,7 @@
pub use roc_gen_llvm::llvm::build::FunctionIterator;
use roc_gen_llvm::llvm::build::{module_from_builtins, LlvmBackendMode};
use roc_gen_llvm::llvm::externs::add_default_roc_externs;
use roc_load::{LoadedModule, MonomorphizedModule};
use roc_load::{EntryPoint, LoadedModule, MonomorphizedModule};
use roc_module::symbol::{Interns, ModuleId};
use roc_mono::ir::OptLevel;
use roc_region::all::LineInfo;
@ -265,11 +265,18 @@ pub fn gen_from_mono_module_llvm(
// expects that would confuse the surgical linker
add_default_roc_externs(&env);
let opt_entry_point = match loaded.entry_point {
EntryPoint::Executable { symbol, layout, .. } => {
Some(roc_mono::ir::EntryPoint { symbol, layout })
}
EntryPoint::Test => None,
};
roc_gen_llvm::llvm::build::build_procedures(
&env,
opt_level,
loaded.procedures,
loaded.entry_point,
opt_entry_point,
Some(&app_ll_file),
);

View file

@ -4220,10 +4220,16 @@ pub fn build_procedures<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
opt_level: OptLevel,
procedures: MutMap<(Symbol, ProcLayout<'a>), roc_mono::ir::Proc<'a>>,
entry_point: EntryPoint<'a>,
opt_entry_point: Option<EntryPoint<'a>>,
debug_output_file: Option<&Path>,
) {
build_procedures_help(env, opt_level, procedures, entry_point, debug_output_file);
build_procedures_help(
env,
opt_level,
procedures,
opt_entry_point,
debug_output_file,
);
}
pub fn build_wasm_test_wrapper<'a, 'ctx, 'env>(
@ -4236,7 +4242,7 @@ pub fn build_wasm_test_wrapper<'a, 'ctx, 'env>(
env,
opt_level,
procedures,
entry_point,
Some(entry_point),
Some(Path::new("/tmp/test.ll")),
);
@ -4253,7 +4259,7 @@ pub fn build_procedures_return_main<'a, 'ctx, 'env>(
env,
opt_level,
procedures,
entry_point,
Some(entry_point),
Some(Path::new("/tmp/test.ll")),
);
@ -4265,13 +4271,13 @@ pub fn build_procedures_expose_expects<'a, 'ctx, 'env>(
opt_level: OptLevel,
expects: &[Symbol],
procedures: MutMap<(Symbol, ProcLayout<'a>), roc_mono::ir::Proc<'a>>,
entry_point: EntryPoint<'a>,
opt_entry_point: Option<EntryPoint<'a>>,
) -> Vec<'a, &'a str> {
let mod_solutions = build_procedures_help(
env,
opt_level,
procedures,
entry_point,
opt_entry_point,
Some(Path::new("/tmp/test.ll")),
);
@ -4333,7 +4339,7 @@ fn build_procedures_help<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
opt_level: OptLevel,
procedures: MutMap<(Symbol, ProcLayout<'a>), roc_mono::ir::Proc<'a>>,
entry_point: EntryPoint<'a>,
opt_entry_point: Option<EntryPoint<'a>>,
debug_output_file: Option<&Path>,
) -> &'a ModSolutions {
let mut layout_ids = roc_mono::layout::LayoutIds::default();
@ -4341,7 +4347,7 @@ fn build_procedures_help<'a, 'ctx, 'env>(
let it = procedures.iter().map(|x| x.1);
let solutions = match roc_alias_analysis::spec_program(opt_level, entry_point, it) {
let solutions = match roc_alias_analysis::spec_program(opt_level, opt_entry_point, it) {
Err(e) => panic!("Error in alias analysis: {}", e),
Ok(solutions) => solutions,
};

View file

@ -1,5 +1,3 @@
pub use roc_load_internal::file::Threading;
use bumpalo::Bump;
use roc_can::module::ExposedByModule;
use roc_collections::all::MutMap;
@ -11,7 +9,8 @@ use std::path::PathBuf;
pub use roc_load_internal::docs;
pub use roc_load_internal::file::{
Expectations, LoadResult, LoadStart, LoadedModule, LoadingProblem, MonomorphizedModule, Phase,
EntryPoint, ExecutionMode, Expectations, LoadConfig, LoadResult, LoadStart, LoadedModule,
LoadingProblem, MonomorphizedModule, Phase, Threading,
};
#[allow(clippy::too_many_arguments)]
@ -19,23 +18,11 @@ fn load<'a>(
arena: &'a Bump,
load_start: LoadStart<'a>,
exposed_types: ExposedByModule,
goal_phase: Phase,
target_info: TargetInfo,
render: RenderTarget,
threading: Threading,
load_config: LoadConfig,
) -> Result<LoadResult<'a>, LoadingProblem<'a>> {
let cached_subs = read_cached_subs();
roc_load_internal::file::load(
arena,
load_start,
exposed_types,
goal_phase,
target_info,
cached_subs,
render,
threading,
)
roc_load_internal::file::load(arena, load_start, exposed_types, cached_subs, load_config)
}
/// Load using only a single thread; used when compiling to webassembly
@ -43,9 +30,9 @@ pub fn load_single_threaded<'a>(
arena: &'a Bump,
load_start: LoadStart<'a>,
exposed_types: ExposedByModule,
goal_phase: Phase,
target_info: TargetInfo,
render: RenderTarget,
exec_mode: ExecutionMode,
) -> Result<LoadResult<'a>, LoadingProblem<'a>> {
let cached_subs = read_cached_subs();
@ -53,10 +40,10 @@ pub fn load_single_threaded<'a>(
arena,
load_start,
exposed_types,
goal_phase,
target_info,
cached_subs,
render,
exec_mode,
)
}
@ -67,23 +54,13 @@ pub fn load_and_monomorphize_from_str<'a>(
src: &'a str,
src_dir: PathBuf,
exposed_types: ExposedByModule,
target_info: TargetInfo,
render: RenderTarget,
threading: Threading,
load_config: LoadConfig,
) -> Result<MonomorphizedModule<'a>, LoadingProblem<'a>> {
use LoadResult::*;
let load_start = LoadStart::from_str(arena, filename, src, src_dir)?;
match load(
arena,
load_start,
exposed_types,
Phase::MakeSpecializations,
target_info,
render,
threading,
)? {
match load(arena, load_start, exposed_types, load_config)? {
Monomorphized(module) => Ok(module),
TypeChecked(_) => unreachable!(""),
}
@ -93,23 +70,13 @@ pub fn load_and_monomorphize(
arena: &Bump,
filename: PathBuf,
exposed_types: ExposedByModule,
target_info: TargetInfo,
render: RenderTarget,
threading: Threading,
load_config: LoadConfig,
) -> Result<MonomorphizedModule<'_>, LoadingProblem<'_>> {
use LoadResult::*;
let load_start = LoadStart::from_path(arena, filename, render)?;
let load_start = LoadStart::from_path(arena, filename, load_config.render)?;
match load(
arena,
load_start,
exposed_types,
Phase::MakeSpecializations,
target_info,
render,
threading,
)? {
match load(arena, load_start, exposed_types, load_config)? {
Monomorphized(module) => Ok(module),
TypeChecked(_) => unreachable!(""),
}
@ -119,23 +86,13 @@ pub fn load_and_typecheck(
arena: &Bump,
filename: PathBuf,
exposed_types: ExposedByModule,
target_info: TargetInfo,
render: RenderTarget,
threading: Threading,
load_config: LoadConfig,
) -> Result<LoadedModule, LoadingProblem<'_>> {
use LoadResult::*;
let load_start = LoadStart::from_path(arena, filename, render)?;
let load_start = LoadStart::from_path(arena, filename, load_config.render)?;
match load(
arena,
load_start,
exposed_types,
Phase::SolveTypes,
target_info,
render,
threading,
)? {
match load(arena, load_start, exposed_types, load_config)? {
Monomorphized(_) => unreachable!(""),
TypeChecked(module) => Ok(module),
}
@ -161,9 +118,9 @@ pub fn load_and_typecheck_str<'a>(
arena,
load_start,
exposed_types,
Phase::SolveTypes,
target_info,
render,
ExecutionMode::Check,
)? {
Monomorphized(_) => unreachable!(""),
TypeChecked(module) => Ok(module),

View file

@ -30,8 +30,8 @@ use roc_module::symbol::{
PackageQualified, Symbol,
};
use roc_mono::ir::{
CapturedSymbols, EntryPoint, ExternalSpecializations, PartialProc, Proc, ProcLayout, Procs,
ProcsBase, UpdateModeIds,
CapturedSymbols, ExternalSpecializations, PartialProc, Proc, ProcLayout, Procs, ProcsBase,
UpdateModeIds,
};
use roc_mono::layout::{CapturesNiche, LambdaName, Layout, LayoutCache, LayoutProblem};
use roc_parse::ast::{self, Defs, ExtractSpaces, Spaced, StrLiteral, TypeAnnotation};
@ -117,6 +117,30 @@ macro_rules! log {
($($arg:tt)*) => (dbg_do!(ROC_PRINT_LOAD_LOG, println!($($arg)*)))
}
#[derive(Debug)]
pub struct LoadConfig {
pub target_info: TargetInfo,
pub render: RenderTarget,
pub threading: Threading,
pub exec_mode: ExecutionMode,
}
#[derive(Debug, Clone, Copy)]
pub enum ExecutionMode {
Test,
Check,
Executable,
}
impl ExecutionMode {
fn goal_phase(&self) -> Phase {
match self {
ExecutionMode::Test | ExecutionMode::Executable => Phase::MakeSpecializations,
ExecutionMode::Check => Phase::SolveTypes,
}
}
}
/// Struct storing various intermediate stages by their ModuleId
#[derive(Debug)]
struct ModuleCache<'a> {
@ -670,7 +694,6 @@ pub struct MonomorphizedModule<'a> {
pub interns: Interns,
pub subs: Subs,
pub output_path: Box<Path>,
pub platform_path: Box<Path>,
pub can_problems: MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
pub type_problems: MutMap<ModuleId, Vec<TypeError>>,
pub procedures: MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
@ -682,6 +705,16 @@ pub struct MonomorphizedModule<'a> {
pub expectations: VecMap<ModuleId, Expectations>,
}
#[derive(Debug)]
pub enum EntryPoint<'a> {
Executable {
symbol: Symbol,
layout: ProcLayout<'a>,
platform_path: Box<Path>,
},
Test,
}
#[derive(Debug)]
pub struct Expectations {
pub subs: roc_types::subs::Subs,
@ -848,7 +881,6 @@ struct State<'a> {
pub root_id: ModuleId,
pub root_subs: Option<Subs>,
pub platform_data: Option<PlatformData>,
pub goal_phase: Phase,
pub exposed_types: ExposedByModule,
pub output_path: Option<&'a str>,
pub platform_path: PlatformPath<'a>,
@ -859,6 +891,7 @@ struct State<'a> {
pub procedures: MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
pub toplevel_expects: VecMap<Symbol, Region>,
pub exposed_to_host: ExposedToHost,
pub goal_phase: Phase,
/// This is the "final" list of IdentIds, after canonicalization and constraint gen
/// have completed for a given module.
@ -886,6 +919,7 @@ struct State<'a> {
pub layout_caches: std::vec::Vec<LayoutCache<'a>>,
pub render: RenderTarget,
pub exec_mode: ExecutionMode,
/// All abilities across all modules.
pub world_abilities: WorldAbilities,
@ -903,16 +937,17 @@ impl<'a> State<'a> {
fn new(
root_id: ModuleId,
target_info: TargetInfo,
goal_phase: Phase,
exposed_types: ExposedByModule,
arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: SharedIdentIdsByModule,
cached_subs: MutMap<ModuleId, (Subs, Vec<(Symbol, Variable)>)>,
render: RenderTarget,
number_of_workers: usize,
exec_mode: ExecutionMode,
) -> Self {
let arc_shorthands = Arc::new(Mutex::new(MutMap::default()));
let goal_phase = exec_mode.goal_phase();
let dependencies = Dependencies::new(goal_phase);
Self {
@ -940,6 +975,7 @@ impl<'a> State<'a> {
layout_caches: std::vec::Vec::with_capacity(number_of_workers),
cached_subs: Arc::new(Mutex::new(cached_subs)),
render,
exec_mode,
make_specializations_pass: MakeSpecializationsPass::Pass(1),
world_abilities: Default::default(),
}
@ -1146,16 +1182,14 @@ pub fn load_and_typecheck_str<'a>(
// where we want to regenerate the cached data
let cached_subs = MutMap::default();
match load(
arena,
load_start,
exposed_types,
Phase::SolveTypes,
let load_config = LoadConfig {
target_info,
cached_subs,
render,
threading,
)? {
exec_mode: ExecutionMode::Check,
};
match load(arena, load_start, exposed_types, cached_subs, load_config)? {
Monomorphized(_) => unreachable!(""),
TypeChecked(module) => Ok(module),
}
@ -1364,11 +1398,8 @@ pub fn load<'a>(
arena: &'a Bump,
load_start: LoadStart<'a>,
exposed_types: ExposedByModule,
goal_phase: Phase,
target_info: TargetInfo,
cached_subs: MutMap<ModuleId, (Subs, Vec<(Symbol, Variable)>)>,
render: RenderTarget,
threading: Threading,
load_config: LoadConfig,
) -> Result<LoadResult<'a>, LoadingProblem<'a>> {
enum Threads {
Single,
@ -1385,7 +1416,7 @@ pub fn load<'a>(
Err(_) => Threads::Single,
Ok(0) => unreachable!("NonZeroUsize"),
Ok(1) => Threads::Single,
Ok(reported) => match threading {
Ok(reported) => match load_config.threading {
Threading::Single => Threads::Single,
Threading::AllAvailable => Threads::Many(reported),
Threading::AtMost(at_most) => Threads::Many(Ord::min(reported, at_most)),
@ -1399,20 +1430,20 @@ pub fn load<'a>(
arena,
load_start,
exposed_types,
goal_phase,
target_info,
load_config.target_info,
cached_subs,
render,
load_config.render,
load_config.exec_mode,
),
Threads::Many(threads) => load_multi_threaded(
arena,
load_start,
exposed_types,
goal_phase,
target_info,
load_config.target_info,
cached_subs,
render,
load_config.render,
threads,
load_config.exec_mode,
),
}
}
@ -1423,10 +1454,10 @@ pub fn load_single_threaded<'a>(
arena: &'a Bump,
load_start: LoadStart<'a>,
exposed_types: ExposedByModule,
goal_phase: Phase,
target_info: TargetInfo,
cached_subs: MutMap<ModuleId, (Subs, Vec<(Symbol, Variable)>)>,
render: RenderTarget,
exec_mode: ExecutionMode,
) -> Result<LoadResult<'a>, LoadingProblem<'a>> {
let LoadStart {
arc_modules,
@ -1447,13 +1478,13 @@ pub fn load_single_threaded<'a>(
let mut state = State::new(
root_id,
target_info,
goal_phase,
exposed_types,
arc_modules,
ident_ids_by_module,
cached_subs,
render,
number_of_workers,
exec_mode,
);
// We'll add tasks to this, and then worker threads will take tasks from it.
@ -1624,11 +1655,11 @@ fn load_multi_threaded<'a>(
arena: &'a Bump,
load_start: LoadStart<'a>,
exposed_types: ExposedByModule,
goal_phase: Phase,
target_info: TargetInfo,
cached_subs: MutMap<ModuleId, (Subs, Vec<(Symbol, Variable)>)>,
render: RenderTarget,
available_threads: usize,
exec_mode: ExecutionMode,
) -> Result<LoadResult<'a>, LoadingProblem<'a>> {
let LoadStart {
arc_modules,
@ -1664,13 +1695,13 @@ fn load_multi_threaded<'a>(
let mut state = State::new(
root_id,
target_info,
goal_phase,
exposed_types,
arc_modules,
ident_ids_by_module,
cached_subs,
render,
num_workers,
exec_mode,
);
// an arena for every worker, stored in an arena-allocated bumpalo vec to make the lifetimes work
@ -2749,6 +2780,7 @@ fn finish_specialization(
output_path,
platform_path,
platform_data,
exec_mode,
..
} = state;
@ -2765,53 +2797,60 @@ fn finish_specialization(
.map(|(id, (path, src))| (id, (path, src.into())))
.collect();
let path_to_platform = {
use PlatformPath::*;
let package_name = match platform_path {
Valid(To::ExistingPackage(shorthand)) => {
match (*state.arc_shorthands).lock().get(shorthand) {
Some(p_or_p) => *p_or_p,
None => unreachable!(),
}
}
Valid(To::NewPackage(p_or_p)) => p_or_p,
other => {
let buf = to_missing_platform_report(state.root_id, other);
return Err(LoadingProblem::FormattedReport(buf));
}
};
package_name.into()
};
let platform_path = Path::new(path_to_platform).into();
let entry_point = {
let symbol = match platform_data {
None => {
debug_assert_eq!(exposed_to_host.values.len(), 1);
*exposed_to_host.values.iter().next().unwrap().0
}
Some(PlatformData { provides, .. }) => provides,
};
match exec_mode {
ExecutionMode::Test => EntryPoint::Test,
ExecutionMode::Executable => {
let path_to_platform = {
use PlatformPath::*;
let package_name = match platform_path {
Valid(To::ExistingPackage(shorthand)) => {
match (*state.arc_shorthands).lock().get(shorthand) {
Some(p_or_p) => *p_or_p,
None => unreachable!(),
}
}
Valid(To::NewPackage(p_or_p)) => p_or_p,
other => {
let buf = to_missing_platform_report(state.root_id, other);
return Err(LoadingProblem::FormattedReport(buf));
}
};
match procedures.keys().find(|(s, _)| *s == symbol) {
Some((_, layout)) => EntryPoint {
layout: *layout,
symbol,
},
None => {
// the entry point is not specialized. This can happen if the repl output
// is a function value
EntryPoint {
layout: roc_mono::ir::ProcLayout {
arguments: &[],
result: Layout::struct_no_name_order(&[]),
captures_niche: CapturesNiche::no_niche(),
package_name.into()
};
let platform_path = Path::new(path_to_platform).into();
let symbol = match platform_data {
None => {
debug_assert_eq!(exposed_to_host.values.len(), 1);
*exposed_to_host.values.iter().next().unwrap().0
}
Some(PlatformData { provides, .. }) => provides,
};
match procedures.keys().find(|(s, _)| *s == symbol) {
Some((_, layout)) => EntryPoint::Executable {
layout: *layout,
symbol,
platform_path,
},
symbol,
None => {
// the entry point is not specialized. This can happen if the repl output
// is a function value
EntryPoint::Executable {
layout: roc_mono::ir::ProcLayout {
arguments: &[],
result: Layout::struct_no_name_order(&[]),
captures_niche: CapturesNiche::no_niche(),
},
symbol,
platform_path,
}
}
}
}
ExecutionMode::Check => unreachable!(),
}
};
@ -2824,7 +2863,7 @@ fn finish_specialization(
can_problems,
type_problems,
output_path,
platform_path,
expectations,
exposed_to_host,
module_id: state.root_id,
subs,
@ -2834,7 +2873,6 @@ fn finish_specialization(
sources,
timings: state.timings,
toplevel_expects,
expectations,
})
}

View file

@ -17,8 +17,8 @@ mod helpers;
use crate::helpers::fixtures_dir;
use bumpalo::Bump;
use roc_can::module::ExposedByModule;
use roc_load_internal::file::Threading;
use roc_load_internal::file::{LoadResult, LoadStart, LoadedModule, LoadingProblem, Phase};
use roc_load_internal::file::{ExecutionMode, LoadConfig, Threading};
use roc_load_internal::file::{LoadResult, LoadStart, LoadedModule, LoadingProblem};
use roc_module::ident::ModuleName;
use roc_module::symbol::{Interns, ModuleId};
use roc_problem::can::Problem;
@ -41,16 +41,19 @@ fn load_and_typecheck(
use LoadResult::*;
let load_start = LoadStart::from_path(arena, filename, RenderTarget::Generic)?;
let load_config = LoadConfig {
target_info,
render: RenderTarget::Generic,
threading: Threading::Single,
exec_mode: ExecutionMode::Check,
};
match roc_load_internal::file::load(
arena,
load_start,
exposed_types,
Phase::SolveTypes,
target_info,
Default::default(), // these tests will re-compile the builtins
RenderTarget::Generic,
Threading::Single,
load_config,
)? {
Monomorphized(_) => unreachable!(""),
TypeChecked(module) => Ok(module),

View file

@ -15,8 +15,6 @@ use indoc::indoc;
#[allow(unused_imports)]
use roc_std::{RocList, RocResult, RocStr};
use core::convert::Infallible;
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn roc_list_construction() {
@ -287,6 +285,8 @@ fn list_map_try_ok() {
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn list_map_try_err() {
use core::convert::Infallible;
assert_evals_to!(
r#"
List.mapTry [1, 2, 3] \_ -> Err -1

View file

@ -1,7 +1,7 @@
use libloading::Library;
use roc_build::link::{link, LinkType};
use roc_builtins::bitcode;
use roc_load::Threading;
use roc_load::{EntryPoint, ExecutionMode, LoadConfig, Threading};
use roc_region::all::LineInfo;
use tempfile::tempdir;
@ -50,15 +50,19 @@ pub fn helper(
module_src = &temp;
}
let load_config = LoadConfig {
target_info: roc_target::TargetInfo::default_x86_64(),
render: roc_reporting::report::RenderTarget::ColorTerminal,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
};
let loaded = roc_load::load_and_monomorphize_from_str(
arena,
filename,
module_src,
src_dir,
Default::default(),
roc_target::TargetInfo::default_x86_64(),
roc_reporting::report::RenderTarget::ColorTerminal,
Threading::Single,
load_config,
);
let mut loaded = loaded.expect("failed to load module");
@ -96,8 +100,16 @@ pub fn helper(
}
debug_assert_eq!(exposed_to_host.values.len(), 1);
let main_fn_symbol = loaded.entry_point.symbol;
let main_fn_layout = loaded.entry_point.layout;
let entry_point = match loaded.entry_point {
EntryPoint::Executable { symbol, layout, .. } => {
roc_mono::ir::EntryPoint { symbol, layout }
}
EntryPoint::Test => {
unreachable!()
}
};
let main_fn_symbol = entry_point.symbol;
let main_fn_layout = entry_point.layout;
let mut layout_ids = roc_mono::layout::LayoutIds::default();
let main_fn_name = layout_ids

View file

@ -7,7 +7,7 @@ use roc_build::program::FunctionIterator;
use roc_collections::all::MutSet;
use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_gen_llvm::llvm::externs::add_default_roc_externs;
use roc_load::Threading;
use roc_load::{EntryPoint, ExecutionMode, LoadConfig, Threading};
use roc_mono::ir::OptLevel;
use roc_region::all::LineInfo;
use roc_reporting::report::RenderTarget;
@ -66,15 +66,19 @@ fn create_llvm_module<'a>(
module_src = &temp;
}
let load_config = LoadConfig {
target_info,
render: RenderTarget::ColorTerminal,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
};
let loaded = roc_load::load_and_monomorphize_from_str(
arena,
filename,
module_src,
src_dir,
Default::default(),
target_info,
RenderTarget::ColorTerminal,
Threading::Single,
load_config,
);
let mut loaded = match loaded {
@ -226,6 +230,14 @@ fn create_llvm_module<'a>(
// platform to provide them.
add_default_roc_externs(&env);
let entry_point = match entry_point {
EntryPoint::Executable { symbol, layout, .. } => {
roc_mono::ir::EntryPoint { symbol, layout }
}
EntryPoint::Test => {
unreachable!()
}
};
let (main_fn_name, main_fn) = match config.mode {
LlvmBackendMode::Binary => unreachable!(),
LlvmBackendMode::CliTest => unreachable!(),

View file

@ -4,7 +4,7 @@ use roc_collections::all::MutSet;
use roc_gen_wasm::wasm32_result::Wasm32Result;
use roc_gen_wasm::wasm_module::{Export, ExportType};
use roc_gen_wasm::DEBUG_SETTINGS;
use roc_load::Threading;
use roc_load::{ExecutionMode, LoadConfig, Threading};
use std::marker::PhantomData;
use std::path::PathBuf;
use std::rc::Rc;
@ -35,9 +35,9 @@ fn promote_expr_to_module(src: &str) -> String {
}
fn write_final_wasm() -> bool {
use roc_debug_flags::{dbg_do, ROC_WRITE_FINAL_WASM};
use roc_debug_flags::dbg_do;
dbg_do!(ROC_WRITE_FINAL_WASM, {
dbg_do!(roc_debug_flags::ROC_WRITE_FINAL_WASM, {
return true;
});
@ -84,15 +84,19 @@ fn compile_roc_to_wasm_bytes<'a, T: Wasm32Result>(
module_src = &temp;
}
let load_config = LoadConfig {
target_info: roc_target::TargetInfo::default_wasm32(),
render: roc_reporting::report::RenderTarget::ColorTerminal,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
};
let loaded = roc_load::load_and_monomorphize_from_str(
arena,
filename,
module_src,
src_dir,
Default::default(),
roc_target::TargetInfo::default_wasm32(),
roc_reporting::report::RenderTarget::ColorTerminal,
Threading::Single,
load_config,
);
let loaded = loaded.expect("failed to load module");

View file

@ -13,6 +13,8 @@ extern crate indoc;
#[allow(dead_code)]
const EXPANDED_STACK_SIZE: usize = 8 * 1024 * 1024;
use roc_load::ExecutionMode;
use roc_load::LoadConfig;
use test_mono_macros::*;
use roc_collections::all::MutMap;
@ -91,15 +93,19 @@ fn compiles_to_ir(test_name: &str, src: &str) {
module_src = &temp;
}
let load_config = LoadConfig {
target_info: TARGET_INFO,
threading: Threading::Single,
render: roc_reporting::report::RenderTarget::Generic,
exec_mode: ExecutionMode::Executable,
};
let loaded = roc_load::load_and_monomorphize_from_str(
arena,
filename,
module_src,
src_dir,
Default::default(),
TARGET_INFO,
roc_reporting::report::RenderTarget::Generic,
Threading::Single,
load_config,
);
let mut loaded = match loaded {

View file

@ -10,7 +10,7 @@ use roc_highlight::highlight_parser::{highlight_defs, highlight_expr};
use roc_load::docs::DocEntry::DocDef;
use roc_load::docs::{DocEntry, TypeAnnotation};
use roc_load::docs::{ModuleDocumentation, RecordField};
use roc_load::{LoadedModule, LoadingProblem, Threading};
use roc_load::{ExecutionMode, LoadConfig, LoadedModule, LoadingProblem, Threading};
use roc_module::symbol::{IdentIdsByModule, Interns, ModuleId};
use roc_parse::ident::{parse_ident, Ident};
use roc_parse::state::State;
@ -432,14 +432,13 @@ pub fn load_modules_for_files(filenames: Vec<PathBuf>) -> Vec<LoadedModule> {
let mut modules = Vec::with_capacity(filenames.len());
for filename in filenames {
match roc_load::load_and_typecheck(
&arena,
filename,
Default::default(),
roc_target::TargetInfo::default_x86_64(), // This is just type-checking for docs, so "target" doesn't matter
roc_reporting::report::RenderTarget::ColorTerminal,
Threading::AllAvailable,
) {
let load_config = LoadConfig {
target_info: roc_target::TargetInfo::default_x86_64(), // This is just type-checking for docs, so "target" doesn't matter
render: roc_reporting::report::RenderTarget::ColorTerminal,
threading: Threading::AllAvailable,
exec_mode: ExecutionMode::Check,
};
match roc_load::load_and_typecheck(&arena, filename, Default::default(), load_config) {
Ok(loaded) => modules.push(loaded),
Err(LoadingProblem::FormattedReport(report)) => {
eprintln!("{}", report);

View file

@ -1,7 +1,7 @@
use crate::rust_glue;
use crate::types::{Env, Types};
use bumpalo::Bump;
use roc_load::{LoadedModule, LoadingProblem, Threading};
use roc_load::{ExecutionMode, LoadConfig, LoadedModule, LoadingProblem, Threading};
use roc_reporting::report::RenderTarget;
use roc_target::{Architecture, OperatingSystem, TargetInfo};
use std::fs::File;
@ -83,9 +83,12 @@ pub fn load_types(
arena,
full_file_path,
subs_by_module,
target_info,
RenderTarget::Generic,
threading,
LoadConfig {
target_info,
render: RenderTarget::Generic,
threading,
exec_mode: ExecutionMode::Check,
},
)
.unwrap_or_else(|problem| match problem {
LoadingProblem::FormattedReport(report) => {

View file

@ -15,7 +15,7 @@ use roc_build::link::llvm_module_to_dylib;
use roc_collections::all::MutSet;
use roc_gen_llvm::llvm::externs::add_default_roc_externs;
use roc_gen_llvm::{run_jit_function, run_jit_function_dynamic_type};
use roc_load::MonomorphizedModule;
use roc_load::{EntryPoint, MonomorphizedModule};
use roc_mono::ir::OptLevel;
use roc_parse::ast::Expr;
use roc_parse::parser::{EExpr, ELambda, SyntaxError};
@ -239,6 +239,15 @@ pub fn mono_module_to_dylib<'a>(
// platform to provide them.
add_default_roc_externs(&env);
let entry_point = match entry_point {
EntryPoint::Executable { symbol, layout, .. } => {
roc_mono::ir::EntryPoint { symbol, layout }
}
EntryPoint::Test => {
unreachable!()
}
};
let (main_fn_name, main_fn) = roc_gen_llvm::llvm::build::build_procedures_return_main(
&env,
opt_level,

View file

@ -1,5 +1,5 @@
use bumpalo::Bump;
use roc_load::Threading;
use roc_load::{ExecutionMode, LoadConfig, Threading};
use roc_reporting::report::Palette;
use std::path::PathBuf;
@ -60,9 +60,12 @@ pub fn compile_to_mono<'a>(
module_src,
src_dir,
exposed_types,
target_info,
roc_reporting::report::RenderTarget::ColorTerminal,
Threading::Single,
LoadConfig {
target_info,
render: roc_reporting::report::RenderTarget::ColorTerminal,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
},
);
let mut loaded = match loaded {

View file

@ -80,7 +80,7 @@ mod test {
use indoc::indoc;
use pretty_assertions::assert_eq;
use roc_gen_llvm::{llvm::build::LlvmBackendMode, run_roc::RocCallResult, run_roc_dylib};
use roc_load::Threading;
use roc_load::{ExecutionMode, LoadConfig, Threading};
use roc_reporting::report::RenderTarget;
use target_lexicon::Triple;
@ -104,15 +104,19 @@ mod test {
std::fs::write(&filename, source).unwrap();
let load_config = LoadConfig {
target_info,
render: RenderTarget::ColorTerminal,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
};
let loaded = roc_load::load_and_monomorphize_from_str(
arena,
filename,
source,
src_dir.path().to_path_buf(),
Default::default(),
target_info,
RenderTarget::ColorTerminal,
Threading::Single,
load_config,
)
.unwrap();

View file

@ -4,7 +4,7 @@ use inkwell::context::Context;
use roc_build::link::llvm_module_to_dylib;
use roc_collections::{MutSet, VecMap};
use roc_gen_llvm::llvm::{build::LlvmBackendMode, externs::add_default_roc_externs};
use roc_load::{Expectations, MonomorphizedModule};
use roc_load::{EntryPoint, Expectations, MonomorphizedModule};
use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_mono::ir::OptLevel;
use roc_region::all::Region;
@ -299,12 +299,19 @@ pub fn expect_mono_module_to_dylib<'a>(
// platform to provide them.
add_default_roc_externs(&env);
let opt_entry_point = match entry_point {
EntryPoint::Executable { symbol, layout, .. } => {
Some(roc_mono::ir::EntryPoint { symbol, layout })
}
EntryPoint::Test => None,
};
let expect_names = roc_gen_llvm::llvm::build::build_procedures_expose_expects(
&env,
opt_level,
toplevel_expects.unzip_slices().0,
procedures,
entry_point,
opt_entry_point,
);
let expects = bumpalo::collections::Vec::from_iter_in(

View file

@ -13,7 +13,7 @@ mod test_reporting {
use indoc::indoc;
use roc_can::abilities::AbilitiesStore;
use roc_can::expr::PendingDerives;
use roc_load::{self, LoadedModule, LoadingProblem, Threading};
use roc_load::{self, ExecutionMode, LoadConfig, LoadedModule, LoadingProblem, Threading};
use roc_module::symbol::{Interns, ModuleId};
use roc_region::all::LineInfo;
use roc_reporting::report::{
@ -83,14 +83,14 @@ mod test_reporting {
let full_file_path = file_path.clone();
let mut file = File::create(file_path).unwrap();
writeln!(file, "{}", module_src).unwrap();
let result = roc_load::load_and_typecheck(
arena,
full_file_path,
exposed_types,
roc_target::TargetInfo::default_x86_64(),
RenderTarget::Generic,
Threading::Single,
);
let load_config = LoadConfig {
target_info: roc_target::TargetInfo::default_x86_64(),
render: RenderTarget::Generic,
threading: Threading::Single,
exec_mode: ExecutionMode::Check,
};
let result =
roc_load::load_and_typecheck(arena, full_file_path, exposed_types, load_config);
drop(file);
result