Merge pull request #829 from rtfeldman/functions-in-repl

Functions in repl
This commit is contained in:
Richard Feldman 2020-12-26 23:38:53 -05:00 committed by GitHub
commit 16df2c8bcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 138 additions and 47 deletions

View file

@ -20,7 +20,7 @@ use roc_module::symbol::{
use roc_mono::ir::{
CapturedSymbols, ExternalSpecializations, PartialProc, PendingSpecialization, Proc, Procs,
};
use roc_mono::layout::{Layout, LayoutCache};
use roc_mono::layout::{Layout, LayoutCache, LayoutProblem};
use roc_parse::ast::{self, Attempting, StrLiteral, TypeAnnotation};
use roc_parse::header::{
ExposesEntry, ImportsEntry, PackageEntry, PackageOrPath, PlatformHeader, To, TypedIdent,
@ -3508,9 +3508,20 @@ fn add_def_to_module<'a>(
mono_env.subs,
) {
Ok(l) => l,
Err(err) => {
// a host-exposed function is not monomorphized
todo!("The host-exposed function {:?} does not have a valid layout (e.g. maybe the function wasn't monomorphic): {:?}", symbol, err)
Err(LayoutProblem::Erroneous) => {
let message = "top level function has erroneous type";
procs.runtime_errors.insert(symbol, message);
return;
}
Err(LayoutProblem::UnresolvedTypeVar(v)) => {
let message = format!(
"top level function has unresolved type variable {:?}",
v
);
procs
.runtime_errors
.insert(symbol, mono_env.arena.alloc(message));
return;
}
};
@ -3542,9 +3553,29 @@ fn add_def_to_module<'a>(
// get specialized!
if is_exposed {
let annotation = def.expr_var;
let layout = layout_cache.from_var(mono_env.arena, annotation, mono_env.subs).unwrap_or_else(|err|
todo!("TODO gracefully handle the situation where we expose a function to the host which doesn't have a valid layout (e.g. maybe the function wasn't monomorphic): {:?}", err)
);
let layout = match layout_cache.from_var(
mono_env.arena,
annotation,
mono_env.subs,
) {
Ok(l) => l,
Err(LayoutProblem::Erroneous) => {
let message = "top level function has erroneous type";
procs.runtime_errors.insert(symbol, message);
return;
}
Err(LayoutProblem::UnresolvedTypeVar(v)) => {
let message = format!(
"top level function has unresolved type variable {:?}",
v
);
procs
.runtime_errors
.insert(symbol, mono_env.arena.alloc(message));
return;
}
};
procs.insert_exposed(
symbol,

View file

@ -1508,7 +1508,6 @@ pub fn specialize_all<'a>(
));
procs.runtime_errors.insert(name, error_msg);
panic!("failed to specialize {:?}", name);
}
}
}
@ -4869,9 +4868,7 @@ fn reuse_function_symbol<'a>(
// this symbol is a function, that is used by-name (e.g. as an argument to another
// function). Register it with the current variable, then create a function pointer
// to it in the IR.
let layout = layout_cache
.from_var(env.arena, arg_var, env.subs)
.expect("creating layout does not fail");
let res_layout = layout_cache.from_var(env.arena, arg_var, env.subs);
// we have three kinds of functions really. Plain functions, closures by capture,
// and closures by unification. Here we record whether this function captures
@ -4879,8 +4876,8 @@ fn reuse_function_symbol<'a>(
let captures = partial_proc.captured_symbols.captures();
let captured = partial_proc.captured_symbols.clone();
match layout {
Layout::Closure(argument_layouts, closure_layout, ret_layout) if captures => {
match res_layout {
Ok(Layout::Closure(argument_layouts, closure_layout, ret_layout)) if captures => {
// this is a closure by capture, meaning it itself captures local variables.
// we've defined the closure as a (function_ptr, closure_data) pair already
@ -4958,7 +4955,7 @@ fn reuse_function_symbol<'a>(
stmt
}
_ => {
Ok(layout) => {
procs.insert_passed_by_name(
env,
arg_var,
@ -4974,6 +4971,17 @@ fn reuse_function_symbol<'a>(
env.arena.alloc(result),
)
}
Err(LayoutProblem::Erroneous) => {
let message = format!("The {:?} symbol has an erroneous type", symbol);
Stmt::RuntimeError(env.arena.alloc(message))
}
Err(LayoutProblem::UnresolvedTypeVar(v)) => {
let message = format!(
"The {:?} symbol contains a unresolved type var {:?}",
symbol, v
);
Stmt::RuntimeError(env.arena.alloc(message))
}
}
}
}