mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-02 19:32:17 +00:00
Merge branch 'main' into inline-imports
This commit is contained in:
commit
d5a38a26db
667 changed files with 22300 additions and 14562 deletions
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>)>,
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue