Merge branch 'main' into inline-imports

This commit is contained in:
Agus Zubiaga 2024-04-20 12:01:11 -03:00
commit d5a38a26db
No known key found for this signature in database
667 changed files with 22300 additions and 14562 deletions

View file

@ -61,7 +61,7 @@ use roc_reporting::report::{to_file_problem_report_string, Palette, RenderTarget
use roc_solve::module::{extract_module_owned_implementations, SolveConfig, Solved, SolvedModule};
use roc_solve::FunctionKind;
use roc_solve_problem::TypeError;
use roc_target::TargetInfo;
use roc_target::Target;
use roc_types::subs::{CopiedImport, ExposedTypesStorageSubs, Subs, VarStore, Variable};
use roc_types::types::{Alias, Types};
use std::collections::hash_map::Entry::{Occupied, Vacant};
@ -101,7 +101,7 @@ macro_rules! log {
#[derive(Debug)]
pub struct LoadConfig {
pub target_info: TargetInfo,
pub target: Target,
pub render: RenderTarget,
pub palette: Palette,
pub threading: Threading,
@ -220,7 +220,7 @@ fn start_phase<'a>(
//
// At the end of this loop, dep_idents contains all the information to
// resolve a symbol from another module: if it's in here, that means
// we have both imported the module and the ident was exported by that mdoule.
// we have both imported the module and the ident was exported by that module.
for dep_id in deps_by_name.values() {
// We already verified that these are all present,
// so unwrapping should always succeed here.
@ -456,7 +456,7 @@ fn start_phase<'a>(
Subs::default(),
None, // no expectations for derived module
ProcsBase::default(),
LayoutCache::new(state.layout_interner.fork(), state.target_info),
LayoutCache::new(state.layout_interner.fork(), state.target),
ModuleTiming::new(Instant::now()),
)
} else if state.make_specializations_pass.current_pass() == 1 {
@ -515,7 +515,7 @@ fn start_phase<'a>(
&mut ident_ids,
&state.derived_module,
&mut module_timing,
state.target_info,
state.target,
&state.exposed_types,
&mut procs_base,
&mut state.world_abilities,
@ -694,7 +694,7 @@ struct State<'a> {
pub platform_data: Option<PlatformData<'a>>,
pub exposed_types: ExposedByModule,
pub platform_path: PlatformPath<'a>,
pub target_info: TargetInfo,
pub target: Target,
pub(self) function_kind: FunctionKind,
/// Note: only packages and platforms actually expose any modules;
@ -705,7 +705,7 @@ struct State<'a> {
pub dependencies: Dependencies<'a>,
pub procedures: MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
pub host_exposed_lambda_sets: HostExposedLambdaSets<'a>,
pub toplevel_expects: ToplevelExpects,
pub toplevel_expects: MutMap<ModuleId, ToplevelExpects>,
pub exposed_to_host: ExposedToHost,
/// This is the "final" list of IdentIds, after canonicalization and constraint gen
@ -758,7 +758,7 @@ impl<'a> State<'a> {
root_id: ModuleId,
root_path: PathBuf,
opt_platform_shorthand: Option<&'a str>,
target_info: TargetInfo,
target: Target,
function_kind: FunctionKind,
exposed_types: ExposedByModule,
arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
@ -779,7 +779,7 @@ impl<'a> State<'a> {
root_subs: None,
opt_platform_shorthand,
cache_dir,
target_info,
target,
function_kind,
platform_data: None,
platform_path: PlatformPath::NotSpecified,
@ -787,7 +787,7 @@ impl<'a> State<'a> {
dependencies,
procedures: MutMap::default(),
host_exposed_lambda_sets: std::vec::Vec::new(),
toplevel_expects: ToplevelExpects::default(),
toplevel_expects: MutMap::default(),
exposed_to_host: ExposedToHost::default(),
exposed_modules: &[],
exposed_types,
@ -806,7 +806,7 @@ impl<'a> State<'a> {
exec_mode,
make_specializations_pass: MakeSpecializationsPass::Pass(1),
world_abilities: Default::default(),
layout_interner: GlobalLayoutInterner::with_capacity(128, target_info),
layout_interner: GlobalLayoutInterner::with_capacity(128, target),
}
}
}
@ -1038,7 +1038,7 @@ pub fn load_and_typecheck_str<'a>(
source: &'a str,
src_dir: PathBuf,
exposed_types: ExposedByModule,
target_info: TargetInfo,
target: Target,
function_kind: FunctionKind,
render: RenderTarget,
palette: Palette,
@ -1054,7 +1054,7 @@ pub fn load_and_typecheck_str<'a>(
let cached_subs = MutMap::default();
let load_config = LoadConfig {
target_info,
target,
render,
palette,
threading,
@ -1322,7 +1322,7 @@ pub fn load<'a>(
arena,
load_start,
exposed_types,
load_config.target_info,
load_config.target,
load_config.function_kind,
cached_types,
load_config.render,
@ -1334,7 +1334,7 @@ pub fn load<'a>(
arena,
load_start,
exposed_types,
load_config.target_info,
load_config.target,
load_config.function_kind,
cached_types,
load_config.render,
@ -1351,7 +1351,7 @@ pub fn load_single_threaded<'a>(
arena: &'a Bump,
load_start: LoadStart<'a>,
exposed_types: ExposedByModule,
target_info: TargetInfo,
target: Target,
function_kind: FunctionKind,
cached_types: MutMap<ModuleId, TypeState>,
render: RenderTarget,
@ -1381,7 +1381,7 @@ pub fn load_single_threaded<'a>(
root_id,
root_path,
opt_platform_shorthand,
target_info,
target,
function_kind,
exposed_types,
arc_modules,
@ -1432,7 +1432,7 @@ pub fn load_single_threaded<'a>(
&msg_tx,
&src_dir,
roc_cache_dir,
target_info,
target,
);
match control_flow {
@ -1677,7 +1677,7 @@ fn load_multi_threaded<'a>(
arena: &'a Bump,
load_start: LoadStart<'a>,
exposed_types: ExposedByModule,
target_info: TargetInfo,
target: Target,
function_kind: FunctionKind,
cached_types: MutMap<ModuleId, TypeState>,
render: RenderTarget,
@ -1723,7 +1723,7 @@ fn load_multi_threaded<'a>(
root_id,
root_path,
opt_platform_shorthand,
target_info,
target,
function_kind,
exposed_types,
arc_modules,
@ -1799,7 +1799,7 @@ fn load_multi_threaded<'a>(
msg_tx,
src_dir,
roc_cache_dir,
target_info,
target,
)
});
@ -1906,7 +1906,7 @@ fn load_multi_threaded<'a>(
// &mut can_problems_recorded,
// &mut type_problems_recorded,
// )
// .print_to_stdout(Duration::default()); // TODO determine total elapsed time and use it here
// .print_error_warning_count(Duration::default()); // TODO determine total elapsed time and use it here
Err(LoadingProblem::FormattedReport(
concat!(
@ -1928,7 +1928,7 @@ fn worker_task_step<'a>(
msg_tx: &MsgSender<'a>,
src_dir: &Path,
roc_cache_dir: RocCacheDir<'_>,
target_info: TargetInfo,
target: Target,
) -> Result<ControlFlow<(), ()>, LoadingProblem<'a>> {
match worker_msg_rx.try_recv() {
Ok(msg) => {
@ -1957,7 +1957,7 @@ fn worker_task_step<'a>(
src_dir,
msg_tx.clone(),
roc_cache_dir,
target_info,
target,
);
match result {
@ -2002,7 +2002,7 @@ fn worker_task<'a>(
msg_tx: MsgSender<'a>,
src_dir: &Path,
roc_cache_dir: RocCacheDir<'_>,
target_info: TargetInfo,
target: Target,
) -> Result<(), LoadingProblem<'a>> {
// Keep listening until we receive a Shutdown msg
for msg in worker_msg_rx.iter() {
@ -2056,7 +2056,7 @@ fn worker_task<'a>(
src_dir,
msg_tx.clone(),
roc_cache_dir,
target_info,
target,
);
match result {
@ -2478,6 +2478,11 @@ fn update<'a>(
state.module_cache.documentation.insert(module_id, docs);
}
state
.module_cache
.exposed_imports
.insert(module_id, constrained_module.module.exposed_imports.clone());
state
.module_cache
.aliases
@ -2523,6 +2528,10 @@ fn update<'a>(
.module_cache
.type_problems
.insert(module_id, solved_module.problems);
state
.module_cache
.exposes
.insert(module_id, solved_module.exposed_vars_by_symbol.clone());
let should_include_expects = (!loc_expects.is_empty() || !loc_dbgs.is_empty()) && {
let modules = state.arc_modules.lock();
@ -2652,7 +2661,7 @@ fn update<'a>(
if state.goal_phase() > Phase::SolveTypes || state.exec_mode.build_if_checks() {
let layout_cache = state.layout_caches.pop().unwrap_or_else(|| {
LayoutCache::new(state.layout_interner.fork(), state.target_info)
LayoutCache::new(state.layout_interner.fork(), state.target)
});
let typechecked = TypeCheckedModule {
@ -2719,8 +2728,9 @@ fn update<'a>(
let subs = solved_subs.into_inner();
state.toplevel_expects.pure.extend(toplevel_expects.pure);
state.toplevel_expects.fx.extend(toplevel_expects.fx);
if !toplevel_expects.pure.is_empty() || !toplevel_expects.fx.is_empty() {
state.toplevel_expects.insert(module_id, toplevel_expects);
}
state
.module_cache
@ -2879,7 +2889,7 @@ fn update<'a>(
}
let layout_interner = {
let mut taken = GlobalLayoutInterner::with_capacity(0, state.target_info);
let mut taken = GlobalLayoutInterner::with_capacity(0, state.target);
std::mem::swap(&mut state.layout_interner, &mut taken);
taken
};
@ -2932,7 +2942,7 @@ fn update<'a>(
arena,
&layout_interner,
module_id,
state.target_info,
state.target,
ident_ids,
&mut update_mode_ids,
&mut state.procedures,
@ -3271,7 +3281,7 @@ fn finish(
exposed_types_storage: ExposedTypesStorageSubs,
resolved_implementations: ResolvedImplementations,
dep_idents: IdentIdsByModule,
mut documentation: VecMap<ModuleId, ModuleDocumentation>,
documentation: VecMap<ModuleId, ModuleDocumentation>,
abilities_store: AbilitiesStore,
//
#[cfg(debug_assertions)] checkmate: Option<roc_checkmate::Collector>,
@ -3310,18 +3320,6 @@ fn finish(
roc_checkmate::dump_checkmate!(checkmate);
let mut docs_by_module = Vec::with_capacity(state.exposed_modules.len());
for module_id in state.exposed_modules.iter() {
let docs = documentation.remove(module_id).unwrap_or_else(|| {
panic!("A module was exposed but didn't have an entry in `documentation` somehow: {module_id:?}");
});
docs_by_module.push(docs);
}
debug_assert_eq!(documentation.len(), 0);
LoadedModule {
module_id: state.root_id,
interns,
@ -3335,11 +3333,15 @@ fn finish(
exposed_values,
exposed_to_host: exposed_vars_by_symbol.into_iter().collect(),
exposed_types_storage,
exposed_modules: state.exposed_modules.into(),
resolved_implementations,
sources,
timings: state.timings,
docs_by_module,
docs_by_module: documentation,
abilities_store,
exposed_imports: state.module_cache.exposed_imports,
imports: state.module_cache.imports,
exposes: state.module_cache.exposes,
}
}
@ -3767,6 +3769,35 @@ struct HeaderOutput<'a> {
opt_platform_shorthand: Option<&'a str>,
}
fn ensure_roc_file<'a>(filename: &Path, src_bytes: &[u8]) -> Result<(), LoadingProblem<'a>> {
match filename.extension() {
Some(ext) => {
if ext != ROC_FILE_EXTENSION {
return Err(LoadingProblem::FileProblem {
filename: filename.to_path_buf(),
error: io::ErrorKind::Unsupported,
});
}
}
None => {
let index = src_bytes
.iter()
.position(|a| *a == b'\n')
.unwrap_or(src_bytes.len());
let frist_line_bytes = src_bytes[0..index].to_vec();
if let Ok(first_line) = String::from_utf8(frist_line_bytes) {
if !(first_line.starts_with("#!") && first_line.contains("roc")) {
return Err(LoadingProblem::FileProblem {
filename: filename.to_path_buf(),
error: std::io::ErrorKind::Unsupported,
});
}
}
}
}
Ok(())
}
fn parse_header<'a>(
arena: &'a Bump,
read_file_duration: Duration,
@ -3785,6 +3816,8 @@ fn parse_header<'a>(
let parsed = roc_parse::module::parse_header(arena, parse_state.clone());
let parse_header_duration = parse_start.elapsed();
ensure_roc_file(&filename, src_bytes)?;
// Insert the first entries for this module's timings
let mut module_timing = ModuleTiming::new(start_time);
@ -4329,7 +4362,7 @@ fn synth_import(subs: &mut Subs, content: roc_types::subs::Content) -> Variable
fn synth_list_len_type(subs: &mut Subs) -> Variable {
use roc_types::subs::{Content, FlatType, LambdaSet, OptVariable, SubsSlice, UnionLabels};
// List.len : List a -> Nat
// List.len : List a -> U64
let a = synth_import(subs, Content::FlexVar(None));
let a_slice = SubsSlice::extend_new(&mut subs.variables, [a]);
let list_a = synth_import(
@ -4337,7 +4370,7 @@ fn synth_list_len_type(subs: &mut Subs) -> Variable {
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, a_slice)),
);
let fn_var = synth_import(subs, Content::Error);
let solved_list_len = UnionLabels::insert_into_subs(subs, [(Symbol::LIST_LEN, [])]);
let solved_list_len = UnionLabels::insert_into_subs(subs, [(Symbol::LIST_LEN_U64, [])]);
let clos_list_len = synth_import(
subs,
Content::LambdaSet(LambdaSet {
@ -4350,7 +4383,7 @@ fn synth_list_len_type(subs: &mut Subs) -> Variable {
let fn_args_slice = SubsSlice::extend_new(&mut subs.variables, [list_a]);
subs.set_content(
fn_var,
Content::Structure(FlatType::Func(fn_args_slice, clos_list_len, Variable::NAT)),
Content::Structure(FlatType::Func(fn_args_slice, clos_list_len, Variable::U64)),
);
fn_var
}
@ -4391,7 +4424,7 @@ pub fn add_imports(
// Num needs List.len, but List imports Num.
let list_len_type_var = synth_list_len_type(subs);
let list_len_type_index = constraints.push_variable(list_len_type_var);
def_types.push((Symbol::LIST_LEN, Loc::at_zero(list_len_type_index)));
def_types.push((Symbol::LIST_LEN_U64, Loc::at_zero(list_len_type_index)));
import_variables.push(list_len_type_var);
}
@ -4529,7 +4562,7 @@ fn import_variable_for_symbol(
// Today we define builtins in each module that uses them
// so even though they have a different module name from
// the surrounding module, they are not technically imported
debug_assert!(symbol.is_builtin());
debug_assert!(symbol.is_builtin(), "The symbol {:?} was not found and was assumed to be a builtin, but it wasn't a builtin.", symbol);
return;
}
AbilityMemberMustBeAvailable => {
@ -5010,36 +5043,22 @@ fn canonicalize_and_constrain<'a>(
// Generate documentation information
// TODO: store timing information?
let module_docs = match header_type {
HeaderType::App { .. } => None,
HeaderType::Platform { .. } | HeaderType::Package { .. } => {
// TODO: actually generate docs for platform and package modules.
None
}
HeaderType::Interface { name, .. }
| HeaderType::Builtin { name, .. }
| HeaderType::Hosted { name, .. }
if exposed_module_ids.contains(&parsed.module_id) =>
{
let module_docs = {
let module_name = header_type.get_name();
module_name.map(|module_name| {
let mut scope = module_output.scope.clone();
scope.add_docs_imports();
let docs = crate::docs::generate_module_docs(
crate::docs::generate_module_docs(
scope,
module_id,
module_ids,
name.as_str().into(),
module_name.into(),
&parsed_defs_for_docs,
exposed_module_ids,
module_output.exposed_symbols.clone(),
parsed.header_comments,
);
Some(docs)
}
HeaderType::Interface { .. } | HeaderType::Builtin { .. } | HeaderType::Hosted { .. } => {
// This module isn't exposed by the platform, so don't generate docs for it!
None
}
)
})
};
// _before has an underscore because it's unused in --release builds
@ -5429,7 +5448,7 @@ fn make_specializations<'a>(
mut layout_cache: LayoutCache<'a>,
specializations_we_must_make: Vec<ExternalSpecializations<'a>>,
mut module_timing: ModuleTiming,
target_info: TargetInfo,
target: Target,
world_abilities: WorldAbilities,
exposed_by_module: &ExposedByModule,
derived_module: SharedDerivedModule,
@ -5444,7 +5463,7 @@ fn make_specializations<'a>(
expectation_subs: expectations.as_mut().map(|e| &mut e.subs),
home,
ident_ids: &mut ident_ids,
target_info,
target,
update_mode_ids: &mut update_mode_ids,
// call_specialization_counter=0 is reserved
call_specialization_counter: 1,
@ -5515,7 +5534,7 @@ fn build_pending_specializations<'a>(
declarations: Declarations,
mut module_timing: ModuleTiming,
mut layout_cache: LayoutCache<'a>,
target_info: TargetInfo,
target: Target,
exposed_to_host: ExposedToHost,
exposed_by_module: &ExposedByModule,
world_abilities: WorldAbilities,
@ -5544,7 +5563,7 @@ fn build_pending_specializations<'a>(
expectation_subs: expectations.as_mut().map(|e| &mut e.subs),
home,
ident_ids: &mut ident_ids,
target_info,
target,
update_mode_ids: &mut update_mode_ids,
// call_specialization_counter=0 is reserved
call_specialization_counter: 1,
@ -5994,7 +6013,7 @@ fn load_derived_partial_procs<'a>(
ident_ids: &mut IdentIds,
derived_module: &SharedDerivedModule,
module_timing: &mut ModuleTiming,
target_info: TargetInfo,
target: Target,
exposed_by_module: &ExposedByModule,
procs_base: &mut ProcsBase<'a>,
world_abilities: &mut WorldAbilities,
@ -6025,7 +6044,7 @@ fn load_derived_partial_procs<'a>(
expectation_subs: None,
home,
ident_ids,
target_info,
target,
update_mode_ids: &mut update_mode_ids,
// call_specialization_counter=0 is reserved
call_specialization_counter: 1,
@ -6099,7 +6118,7 @@ fn run_task<'a>(
src_dir: &Path,
msg_tx: MsgSender<'a>,
roc_cache_dir: RocCacheDir<'_>,
target_info: TargetInfo,
target: Target,
) -> Result<(), LoadingProblem<'a>> {
use BuildTask::*;
@ -6208,7 +6227,7 @@ fn run_task<'a>(
decls,
module_timing,
layout_cache,
target_info,
target,
exposed_to_host,
&exposed_by_module,
world_abilities,
@ -6237,7 +6256,7 @@ fn run_task<'a>(
layout_cache,
specializations_we_must_make,
module_timing,
target_info,
target,
world_abilities,
&exposed_by_module,
derived_module,