remove another result wrapper

This commit is contained in:
Folkert 2022-05-08 17:09:33 +02:00
parent d5b010cb13
commit 2e9477e011
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
2 changed files with 296 additions and 313 deletions

View file

@ -170,7 +170,7 @@ pub fn canonicalize_module_defs<'a>(
exposed_symbols: &VecSet<Symbol>,
symbols_from_requires: &[(Loc<Symbol>, Loc<TypeAnnotation<'a>>)],
var_store: &mut VarStore,
) -> Result<ModuleOutput, RuntimeError> {
) -> ModuleOutput {
let mut can_exposed_imports = MutMap::default();
let mut scope = Scope::new(home, exposed_ident_ids);
let mut env = Env::new(home, dep_idents, module_ids);
@ -351,238 +351,231 @@ pub fn canonicalize_module_defs<'a>(
..Default::default()
};
match sort_can_defs(&mut env, defs, new_output) {
(mut declarations, mut output) => {
use crate::def::Declaration::*;
let (mut declarations, mut output) = sort_can_defs(&mut env, defs, new_output);
let symbols_from_requires = symbols_from_requires
.iter()
.map(|(symbol, loc_ann)| {
let ann = canonicalize_annotation(
&mut env,
&mut scope,
&loc_ann.value,
loc_ann.region,
var_store,
&output.abilities_in_scope,
);
let symbols_from_requires = symbols_from_requires
.iter()
.map(|(symbol, loc_ann)| {
let ann = canonicalize_annotation(
&mut env,
&mut scope,
&loc_ann.value,
loc_ann.region,
var_store,
&output.abilities_in_scope,
);
ann.add_to(
&mut output.aliases,
&mut output.references,
&mut output.introduced_variables,
);
ann.add_to(
&mut output.aliases,
&mut output.references,
&mut output.introduced_variables,
);
(
*symbol,
Loc {
value: ann.typ,
region: loc_ann.region,
},
)
})
.collect();
(
*symbol,
Loc {
value: ann.typ,
region: loc_ann.region,
},
)
})
.collect();
if let GeneratedInfo::Hosted {
effect_symbol,
generated_functions,
} = generated_info
{
let mut exposed_symbols = VecSet::default();
if let GeneratedInfo::Hosted {
effect_symbol,
generated_functions,
} = generated_info
{
let mut exposed_symbols = VecSet::default();
// NOTE this currently builds all functions, not just the ones that the user requested
crate::effect_module::build_effect_builtins(
&mut scope,
effect_symbol,
var_store,
&mut exposed_symbols,
&mut declarations,
generated_functions,
);
// NOTE this currently builds all functions, not just the ones that the user requested
crate::effect_module::build_effect_builtins(
&mut scope,
effect_symbol,
var_store,
&mut exposed_symbols,
&mut declarations,
generated_functions,
);
}
use crate::def::Declaration::*;
for decl in declarations.iter_mut() {
match decl {
Declare(def) => {
for (symbol, _) in def.pattern_vars.iter() {
if exposed_but_not_defined.contains(symbol) {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(symbol);
}
}
// Temporary hack: we don't know exactly what symbols are hosted symbols,
// and which are meant to be normal definitions without a body. So for now
// we just assume they are hosted functions (meant to be provided by the platform)
if has_no_implementation(&def.loc_expr.value) {
match generated_info {
GeneratedInfo::Builtin => {
let symbol = def.pattern_vars.iter().next().unwrap().0;
match crate::builtins::builtin_defs_map(*symbol, var_store) {
None => {
panic!("A builtin module contains a signature without implementation for {:?}", symbol)
}
Some(mut replacement_def) => {
replacement_def.annotation = def.annotation.take();
*def = replacement_def;
}
}
}
GeneratedInfo::Hosted { effect_symbol, .. } => {
let symbol = def.pattern_vars.iter().next().unwrap().0;
let ident_id = symbol.ident_id();
let ident = scope
.locals
.ident_ids
.get_name(ident_id)
.unwrap()
.to_string();
let def_annotation = def.annotation.clone().unwrap();
let annotation = crate::annotation::Annotation {
typ: def_annotation.signature,
introduced_variables: def_annotation.introduced_variables,
references: Default::default(),
aliases: Default::default(),
};
let hosted_def = crate::effect_module::build_host_exposed_def(
&mut scope,
*symbol,
&ident,
effect_symbol,
var_store,
annotation,
);
*def = hosted_def;
}
_ => (),
}
}
}
for decl in declarations.iter_mut() {
match decl {
Declare(def) => {
for (symbol, _) in def.pattern_vars.iter() {
if exposed_but_not_defined.contains(symbol) {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(symbol);
}
DeclareRec(defs) => {
for def in defs {
for (symbol, _) in def.pattern_vars.iter() {
if exposed_but_not_defined.contains(symbol) {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(symbol);
}
// Temporary hack: we don't know exactly what symbols are hosted symbols,
// and which are meant to be normal definitions without a body. So for now
// we just assume they are hosted functions (meant to be provided by the platform)
if has_no_implementation(&def.loc_expr.value) {
match generated_info {
GeneratedInfo::Builtin => {
let symbol = def.pattern_vars.iter().next().unwrap().0;
match crate::builtins::builtin_defs_map(*symbol, var_store) {
None => {
panic!("A builtin module contains a signature without implementation for {:?}", symbol)
}
Some(mut replacement_def) => {
replacement_def.annotation = def.annotation.take();
*def = replacement_def;
}
}
}
GeneratedInfo::Hosted { effect_symbol, .. } => {
let symbol = def.pattern_vars.iter().next().unwrap().0;
let ident_id = symbol.ident_id();
let ident = scope
.locals
.ident_ids
.get_name(ident_id)
.unwrap()
.to_string();
let def_annotation = def.annotation.clone().unwrap();
let annotation = crate::annotation::Annotation {
typ: def_annotation.signature,
introduced_variables: def_annotation.introduced_variables,
references: Default::default(),
aliases: Default::default(),
};
let hosted_def = crate::effect_module::build_host_exposed_def(
&mut scope,
*symbol,
&ident,
effect_symbol,
var_store,
annotation,
);
*def = hosted_def;
}
_ => (),
}
}
}
DeclareRec(defs) => {
for def in defs {
for (symbol, _) in def.pattern_vars.iter() {
if exposed_but_not_defined.contains(symbol) {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(symbol);
}
}
}
}
InvalidCycle(entries) => {
env.problems.push(Problem::BadRecursion(entries.to_vec()));
}
Builtin(def) => {
// Builtins cannot be exposed in module declarations.
// This should never happen!
debug_assert!(def
.pattern_vars
.iter()
.all(|(symbol, _)| !exposed_but_not_defined.contains(symbol)));
}
}
}
let mut aliases = MutMap::default();
if let GeneratedInfo::Hosted { effect_symbol, .. } = generated_info {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(&effect_symbol);
let hosted_alias = scope.lookup_alias(effect_symbol).unwrap().clone();
aliases.insert(effect_symbol, hosted_alias);
InvalidCycle(entries) => {
env.problems.push(Problem::BadRecursion(entries.to_vec()));
}
for (symbol, alias) in output.aliases {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(&symbol);
aliases.insert(symbol, alias);
Builtin(def) => {
// Builtins cannot be exposed in module declarations.
// This should never happen!
debug_assert!(def
.pattern_vars
.iter()
.all(|(symbol, _)| !exposed_but_not_defined.contains(symbol)));
}
for member in scope.abilities_store.root_ability_members().keys() {
exposed_but_not_defined.remove(member);
}
// By this point, all exposed symbols should have been removed from
// exposed_symbols and added to exposed_vars_by_symbol. If any were
// not, that means they were declared as exposed but there was
// no actual declaration with that name!
for symbol in exposed_but_not_defined {
env.problem(Problem::ExposedButNotDefined(symbol));
// In case this exposed value is referenced by other modules,
// create a decl for it whose implementation is a runtime error.
let mut pattern_vars = SendMap::default();
pattern_vars.insert(symbol, var_store.fresh());
let runtime_error = RuntimeError::ExposedButNotDefined(symbol);
let def = Def {
loc_pattern: Loc::at(Region::zero(), Pattern::Identifier(symbol)),
loc_expr: Loc::at(Region::zero(), Expr::RuntimeError(runtime_error)),
expr_var: var_store.fresh(),
pattern_vars,
annotation: None,
};
declarations.push(Declaration::Declare(def));
}
// Incorporate any remaining output.lookups entries into references.
referenced_values.extend(output.references.value_lookups().copied());
referenced_types.extend(output.references.type_lookups().copied());
// Incorporate any remaining output.calls entries into references.
referenced_values.extend(output.references.calls().copied());
// Gather up all the symbols that were referenced from other modules.
referenced_values.extend(env.qualified_value_lookups.iter().copied());
referenced_types.extend(env.qualified_type_lookups.iter().copied());
for declaration in declarations.iter_mut() {
match declaration {
Declare(def) => fix_values_captured_in_closure_def(def, &mut VecSet::default()),
DeclareRec(defs) => {
fix_values_captured_in_closure_defs(defs, &mut VecSet::default())
}
InvalidCycle(_) | Builtin(_) => {}
}
}
let output = ModuleOutput {
scope,
aliases,
rigid_variables,
declarations,
referenced_values,
referenced_types,
exposed_imports: can_exposed_imports,
problems: env.problems,
symbols_from_requires,
lookups,
};
Ok(output)
}
}
let mut aliases = MutMap::default();
if let GeneratedInfo::Hosted { effect_symbol, .. } = generated_info {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(&effect_symbol);
let hosted_alias = scope.lookup_alias(effect_symbol).unwrap().clone();
aliases.insert(effect_symbol, hosted_alias);
}
for (symbol, alias) in output.aliases {
// Remove this from exposed_symbols,
// so that at the end of the process,
// we can see if there were any
// exposed symbols which did not have
// corresponding defs.
exposed_but_not_defined.remove(&symbol);
aliases.insert(symbol, alias);
}
for member in scope.abilities_store.root_ability_members().keys() {
exposed_but_not_defined.remove(member);
}
// By this point, all exposed symbols should have been removed from
// exposed_symbols and added to exposed_vars_by_symbol. If any were
// not, that means they were declared as exposed but there was
// no actual declaration with that name!
for symbol in exposed_but_not_defined {
env.problem(Problem::ExposedButNotDefined(symbol));
// In case this exposed value is referenced by other modules,
// create a decl for it whose implementation is a runtime error.
let mut pattern_vars = SendMap::default();
pattern_vars.insert(symbol, var_store.fresh());
let runtime_error = RuntimeError::ExposedButNotDefined(symbol);
let def = Def {
loc_pattern: Loc::at(Region::zero(), Pattern::Identifier(symbol)),
loc_expr: Loc::at(Region::zero(), Expr::RuntimeError(runtime_error)),
expr_var: var_store.fresh(),
pattern_vars,
annotation: None,
};
declarations.push(Declaration::Declare(def));
}
// Incorporate any remaining output.lookups entries into references.
referenced_values.extend(output.references.value_lookups().copied());
referenced_types.extend(output.references.type_lookups().copied());
// Incorporate any remaining output.calls entries into references.
referenced_values.extend(output.references.calls().copied());
// Gather up all the symbols that were referenced from other modules.
referenced_values.extend(env.qualified_value_lookups.iter().copied());
referenced_types.extend(env.qualified_type_lookups.iter().copied());
for declaration in declarations.iter_mut() {
match declaration {
Declare(def) => fix_values_captured_in_closure_def(def, &mut VecSet::default()),
DeclareRec(defs) => fix_values_captured_in_closure_defs(defs, &mut VecSet::default()),
InvalidCycle(_) | Builtin(_) => {}
}
}
ModuleOutput {
scope,
aliases,
rigid_variables,
declarations,
referenced_values,
referenced_types,
exposed_imports: can_exposed_imports,
problems: env.problems,
symbols_from_requires,
lookups,
}
}
fn fix_values_captured_in_closure_def(