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

@ -18,10 +18,22 @@ pub struct ModuleDocumentation {
pub exposed_symbols: VecSet<Symbol>,
}
impl ModuleDocumentation {
pub fn get_doc_for_symbol(&self, symbol_to_match: &Symbol) -> Option<String> {
self.entries.iter().find_map(|doc| match doc {
DocEntry::DocDef(DocDef { symbol, docs, .. }) if symbol == symbol_to_match => {
docs.clone()
}
_ => None,
})
}
}
#[derive(Debug, Clone)]
pub enum DocEntry {
DocDef(DocDef),
DetachedDoc(String),
ModuleDoc(String),
}
#[derive(Debug, Clone)]
@ -174,10 +186,10 @@ fn generate_entry_docs(
) -> Vec<DocEntry> {
use roc_parse::ast::Pattern;
let mut acc = Vec::with_capacity(defs.tags.len() + 1);
let mut doc_entries = Vec::with_capacity(defs.tags.len() + 1);
if let Some(docs) = comments_or_new_lines_to_docs(header_comments) {
acc.push(DetachedDoc(docs));
doc_entries.push(DocEntry::ModuleDoc(docs));
}
let mut before_comments_or_new_lines: Option<&[CommentOrNewline]> = None;
@ -200,7 +212,11 @@ fn generate_entry_docs(
match either_index.split() {
Err(value_index) => match &defs.value_defs[value_index.index()] {
ValueDef::Annotation(loc_pattern, loc_ann) => {
if let Pattern::Identifier(identifier) = loc_pattern.value {
if let Pattern::Identifier {
ident: identifier,
suffixed: _,
} = loc_pattern.value
{
// Check if this module exposes the def
if let Some(ident_id) = ident_ids.get_id(identifier) {
let name = identifier.to_string();
@ -211,7 +227,7 @@ fn generate_entry_docs(
type_vars: Vec::new(),
docs,
};
acc.push(DocEntry::DocDef(doc_def));
doc_entries.push(DocEntry::DocDef(doc_def));
}
}
}
@ -221,7 +237,11 @@ fn generate_entry_docs(
ann_type,
..
} => {
if let Pattern::Identifier(identifier) = ann_pattern.value {
if let Pattern::Identifier {
ident: identifier,
suffixed: _,
} = ann_pattern.value
{
// Check if this module exposes the def
if let Some(ident_id) = ident_ids.get_id(identifier) {
let doc_def = DocDef {
@ -231,13 +251,29 @@ fn generate_entry_docs(
symbol: Symbol::new(home, ident_id),
docs,
};
acc.push(DocEntry::DocDef(doc_def));
doc_entries.push(DocEntry::DocDef(doc_def));
}
}
}
ValueDef::Body(_, _) => {
// TODO generate docs for un-annotated bodies
ValueDef::Body(pattern, _) => {
if let Pattern::Identifier {
ident: identifier,
suffixed: _,
} = pattern.value
{
// Check if this module exposes the def
if let Some(ident_id) = ident_ids.get_id(identifier) {
let doc_def = DocDef {
name: identifier.to_string(),
type_annotation: TypeAnnotation::NoTypeAnn,
type_vars: Vec::new(),
symbol: Symbol::new(home, ident_id),
docs,
};
doc_entries.push(DocEntry::DocDef(doc_def));
}
}
}
ValueDef::Dbg { .. } => {
@ -257,7 +293,27 @@ fn generate_entry_docs(
ValueDef::IngestedFileImport { .. } => {
// Don't generate docs for ingested file imports
}
ValueDef::Stmt(loc_expr) => {
if let roc_parse::ast::Expr::Var {
ident: identifier, ..
} = loc_expr.value
{
// Check if this module exposes the def
if let Some(ident_id) = ident_ids.get_id(identifier) {
let doc_def = DocDef {
name: identifier.to_string(),
type_annotation: TypeAnnotation::NoTypeAnn,
type_vars: Vec::new(),
symbol: Symbol::new(home, ident_id),
docs,
};
doc_entries.push(DocEntry::DocDef(doc_def));
}
}
}
},
Ok(type_index) => match &defs.type_defs[type_index.index()] {
TypeDef::Alias {
header: TypeHeader { name, vars },
@ -266,7 +322,11 @@ fn generate_entry_docs(
let mut type_vars = Vec::new();
for var in vars.iter() {
if let Pattern::Identifier(ident_name) = var.value {
if let Pattern::Identifier {
ident: ident_name,
suffixed: _,
} = var.value
{
type_vars.push(ident_name.to_string());
}
}
@ -290,7 +350,7 @@ fn generate_entry_docs(
docs,
symbol: Symbol::new(home, ident_id),
};
acc.push(DocEntry::DocDef(doc_def));
doc_entries.push(DocEntry::DocDef(doc_def));
}
TypeDef::Opaque {
@ -300,7 +360,11 @@ fn generate_entry_docs(
let mut type_vars = Vec::new();
for var in vars.iter() {
if let Pattern::Identifier(ident_name) = var.value {
if let Pattern::Identifier {
ident: ident_name,
suffixed: _,
} = var.value
{
type_vars.push(ident_name.to_string());
}
}
@ -313,7 +377,7 @@ fn generate_entry_docs(
docs,
symbol: Symbol::new(home, ident_id),
};
acc.push(DocEntry::DocDef(doc_def));
doc_entries.push(DocEntry::DocDef(doc_def));
}
TypeDef::Ability {
@ -324,7 +388,11 @@ fn generate_entry_docs(
let mut type_vars = Vec::new();
for var in vars.iter() {
if let Pattern::Identifier(ident_name) = var.value {
if let Pattern::Identifier {
ident: ident_name,
suffixed: _,
} = var.value
{
type_vars.push(ident_name.to_string());
}
}
@ -353,7 +421,7 @@ fn generate_entry_docs(
type_vars,
docs,
};
acc.push(DocEntry::DocDef(doc_def));
doc_entries.push(DocEntry::DocDef(doc_def));
}
},
}
@ -365,40 +433,49 @@ fn generate_entry_docs(
let it = before_comments_or_new_lines.iter().flat_map(|e| e.iter());
for detached_doc in detached_docs_from_comments_and_new_lines(it) {
acc.push(DetachedDoc(detached_doc));
doc_entries.push(DetachedDoc(detached_doc));
}
acc
doc_entries
}
/// Does this type contain any types which are not exposed outside the package?
/// (If so, we shouldn't try to render a type annotation for it.)
fn contains_unexposed_type(
ann: &ast::TypeAnnotation,
type_ann: &ast::TypeAnnotation,
exposed_module_ids: &[ModuleId],
module_ids: &ModuleIds,
) -> bool {
use ast::TypeAnnotation::*;
match ann {
match type_ann {
// Apply is the one case that can directly return true.
Apply(module_name, _ident, loc_args) => {
let apply_module_id = module_ids.get_id(&(*module_name).into());
let loc_args_contains_unexposed_type = loc_args.iter().any(|loc_arg| {
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
});
// If the *ident* was unexposed, we would have gotten a naming error
// during canonicalization, so all we need to check is the module.
let module_id = module_ids.get_id(&(*module_name).into()).unwrap();
if let Some(module_id) = apply_module_id {
!exposed_module_ids.contains(&module_id) || loc_args_contains_unexposed_type
} else {
true
}
}
!exposed_module_ids.contains(&module_id)
|| loc_args.iter().any(|loc_arg| {
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
})
}
Malformed(_) | Inferred | Wildcard | BoundVariable(_) => false,
Function(loc_args, loc_ret) => {
let loc_args_contains_unexposed_type = loc_args.iter().any(|loc_arg| {
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
});
contains_unexposed_type(&loc_ret.value, exposed_module_ids, module_ids)
|| loc_args.iter().any(|loc_arg| {
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
})
|| loc_args_contains_unexposed_type
}
Record { fields, ext } => {
if let Some(loc_ext) = ext {
if contains_unexposed_type(&loc_ext.value, exposed_module_ids, module_ids) {
@ -428,6 +505,7 @@ fn contains_unexposed_type(
false
}
Tuple { elems: fields, ext } => {
if let Some(loc_ext) = ext {
if contains_unexposed_type(&loc_ext.value, exposed_module_ids, module_ids) {
@ -439,6 +517,7 @@ fn contains_unexposed_type(
contains_unexposed_type(&loc_field.value, exposed_module_ids, module_ids)
})
}
TagUnion { ext, tags } => {
use ast::Tag;
@ -474,14 +553,17 @@ fn contains_unexposed_type(
false
}
Where(loc_ann, _loc_has_clauses) => {
// We assume all the abilities in the `implements` clause are from exported modules.
// TODO don't assume this! Instead, look them up and verify.
contains_unexposed_type(&loc_ann.value, exposed_module_ids, module_ids)
}
As(loc_ann, _spaces, _type_header) => {
contains_unexposed_type(&loc_ann.value, exposed_module_ids, module_ids)
}
SpaceBefore(ann, _) | ast::TypeAnnotation::SpaceAfter(ann, _) => {
contains_unexposed_type(ann, exposed_module_ids, module_ids)
}
@ -572,7 +654,7 @@ fn type_to_docs(in_func_type_ann: bool, type_annotation: ast::TypeAnnotation) ->
.vars
.iter()
.filter_map(|loc_pattern| match loc_pattern.value {
ast::Pattern::Identifier(ident) => Some(ident.to_string()),
ast::Pattern::Identifier { ident, suffixed: _ } => Some(ident.to_string()),
_ => None,
})
.collect(),

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,

View file

@ -38,14 +38,19 @@ pub struct LoadedModule {
pub exposed_to_host: MutMap<Symbol, Variable>,
pub dep_idents: IdentIdsByModule,
pub exposed_aliases: MutMap<Symbol, Alias>,
pub exposed_modules: Vec<ModuleId>,
pub exposed_values: Vec<Symbol>,
pub exposed_types_storage: ExposedTypesStorageSubs,
pub resolved_implementations: ResolvedImplementations,
pub sources: MutMap<ModuleId, (PathBuf, Box<str>)>,
pub timings: MutMap<ModuleId, ModuleTiming>,
pub docs_by_module: Vec<(ModuleId, ModuleDocumentation)>,
pub docs_by_module: VecMap<ModuleId, ModuleDocumentation>,
pub abilities_store: AbilitiesStore,
pub typechecked: MutMap<ModuleId, CheckedModule>,
pub imports: MutMap<ModuleId, MutSet<ModuleId>>,
pub exposed_imports: MutMap<ModuleId, MutMap<Symbol, Region>>,
pub exposes: MutMap<ModuleId, Vec<(Symbol, Variable)>>,
}
impl LoadedModule {
@ -166,7 +171,7 @@ pub struct MonomorphizedModule<'a> {
pub type_problems: MutMap<ModuleId, Vec<TypeError>>,
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 entry_point: EntryPoint<'a>,
pub exposed_to_host: ExposedToHost,
pub sources: MutMap<ModuleId, (PathBuf, Box<str>)>,

View file

@ -9,7 +9,9 @@ use roc_module::ident::ModuleName;
use roc_module::symbol::{ModuleId, PQModuleName, Symbol};
use roc_mono::ir::ExternalSpecializations;
use roc_problem::Severity;
use roc_region::all::Region;
use roc_solve_problem::TypeError;
use roc_types::subs::Variable;
use roc_types::types::Alias;
use std::path::PathBuf;
@ -33,6 +35,8 @@ pub(crate) struct ModuleCache<'a> {
/// Various information
pub(crate) imports: MutMap<ModuleId, MutSet<ModuleId>>,
pub(crate) exposes: MutMap<ModuleId, Vec<(Symbol, Variable)>>,
pub(crate) exposed_imports: MutMap<ModuleId, MutMap<Symbol, Region>>,
pub(crate) top_level_thunks: MutMap<ModuleId, MutSet<Symbol>>,
pub(crate) documentation: VecMap<ModuleId, ModuleDocumentation>,
pub(crate) can_problems: MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
@ -103,6 +107,8 @@ impl Default for ModuleCache<'_> {
late_specializations: Default::default(),
external_specializations_requested: Default::default(),
imports: Default::default(),
exposed_imports: Default::default(),
exposes: Default::default(),
top_level_thunks: Default::default(),
documentation: Default::default(),
can_problems: Default::default(),