mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Fix inlining and test
This commit is contained in:
parent
3e5627689f
commit
1926adb543
2 changed files with 108 additions and 18 deletions
|
@ -1,4 +1,5 @@
|
||||||
use crate::annotation::IntroducedVariables;
|
use crate::annotation::IntroducedVariables;
|
||||||
|
use crate::builtins::builtin_defs;
|
||||||
use crate::def::{can_defs_with_return, Def};
|
use crate::def::{can_defs_with_return, Def};
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
use crate::num::{
|
use crate::num::{
|
||||||
|
@ -1192,9 +1193,62 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
||||||
let (fn_var, loc_expr, expr_var) = *boxed_tuple;
|
let (fn_var, loc_expr, expr_var) = *boxed_tuple;
|
||||||
|
|
||||||
match loc_expr.value {
|
match loc_expr.value {
|
||||||
Var(symbol) if symbol.is_builtin() => {
|
Var(symbol) if symbol.is_builtin() => match builtin_defs(var_store).get(&symbol) {
|
||||||
todo!("Inline this builtin: {:?}", symbol);
|
Some(Closure(_var, _, recursive, params, boxed_body)) => {
|
||||||
}
|
debug_assert_eq!(*recursive, Recursive::NotRecursive);
|
||||||
|
|
||||||
|
// Since this is a canonicalized Expr, we should have
|
||||||
|
// already detected any arity mismatches and replaced this
|
||||||
|
// with a RuntimeError if there was a mismatch.
|
||||||
|
debug_assert_eq!(params.len(), args.len());
|
||||||
|
|
||||||
|
// Start with the function's body as the answer.
|
||||||
|
let (mut loc_answer, _body_var) = *boxed_body.clone();
|
||||||
|
|
||||||
|
// Wrap the body in one LetNonRec for each argument,
|
||||||
|
// such that at the end we have all the arguments in
|
||||||
|
// scope with the values the caller provided.
|
||||||
|
for ((_param_var, loc_pattern), (expr_var, loc_expr)) in
|
||||||
|
params.iter().cloned().zip(args.into_iter()).rev()
|
||||||
|
{
|
||||||
|
// TODO get the correct vars into here.
|
||||||
|
// Not sure if param_var should be involved.
|
||||||
|
let pattern_vars = SendMap::default();
|
||||||
|
|
||||||
|
// TODO get the actual correct aliases
|
||||||
|
let aliases = SendMap::default();
|
||||||
|
|
||||||
|
let def = Def {
|
||||||
|
loc_pattern,
|
||||||
|
loc_expr,
|
||||||
|
expr_var,
|
||||||
|
pattern_vars,
|
||||||
|
annotation: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
loc_answer = Located {
|
||||||
|
region: Region::zero(),
|
||||||
|
value: LetNonRec(
|
||||||
|
Box::new(def),
|
||||||
|
Box::new(loc_answer),
|
||||||
|
var_store.fresh(),
|
||||||
|
aliases,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
loc_answer.value
|
||||||
|
}
|
||||||
|
Some(_) => {
|
||||||
|
unreachable!("Tried to inline a non-function");
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
unreachable!(
|
||||||
|
"Tried to inline a builtin that wasn't registered: {:?}",
|
||||||
|
symbol
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
// For now, we only inline calls to builtins. Leave this alone!
|
// For now, we only inline calls to builtins. Leave this alone!
|
||||||
Call(Box::new((fn_var, loc_expr, expr_var)), args, called_via)
|
Call(Box::new((fn_var, loc_expr, expr_var)), args, called_via)
|
||||||
|
|
|
@ -14,13 +14,16 @@ mod helpers;
|
||||||
mod can_inline {
|
mod can_inline {
|
||||||
use crate::helpers::{can_expr_with, test_home};
|
use crate::helpers::{can_expr_with, test_home};
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
use roc_can::def::Def;
|
||||||
use roc_can::expr::inline_calls;
|
use roc_can::expr::inline_calls;
|
||||||
use roc_can::expr::Expr::{self, *};
|
use roc_can::expr::Expr::{self, *};
|
||||||
|
use roc_can::pattern::Pattern;
|
||||||
use roc_can::scope::Scope;
|
use roc_can::scope::Scope;
|
||||||
|
use roc_collections::all::SendMap;
|
||||||
use roc_module::operator::CalledVia;
|
use roc_module::operator::CalledVia;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::{Located, Region};
|
use roc_region::all::{Located, Region};
|
||||||
use roc_types::subs::VarStore;
|
use roc_types::subs::{VarStore, Variable};
|
||||||
|
|
||||||
fn assert_inlines_to(input: &str, expected: Expr, var_store: &mut VarStore) {
|
fn assert_inlines_to(input: &str, expected: Expr, var_store: &mut VarStore) {
|
||||||
let arena = Bump::new();
|
let arena = Bump::new();
|
||||||
|
@ -34,6 +37,7 @@ mod can_inline {
|
||||||
#[test]
|
#[test]
|
||||||
fn inline_list_len() {
|
fn inline_list_len() {
|
||||||
let var_store = &mut VarStore::default();
|
let var_store = &mut VarStore::default();
|
||||||
|
let aliases = SendMap::default();
|
||||||
|
|
||||||
assert_inlines_to(
|
assert_inlines_to(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -41,23 +45,55 @@ mod can_inline {
|
||||||
Int.isZero 5
|
Int.isZero 5
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
Expr::Call(
|
LetNonRec(
|
||||||
Box::new((
|
Box::new(Def {
|
||||||
var_store.fresh(),
|
loc_pattern: Located {
|
||||||
Located {
|
|
||||||
region: Region::zero(),
|
region: Region::zero(),
|
||||||
value: Expr::Var(Symbol::FLOAT_EQ),
|
value: Pattern::Identifier(Symbol::INT_IS_ZERO_ARG),
|
||||||
},
|
},
|
||||||
var_store.fresh(),
|
pattern_vars: SendMap::default(),
|
||||||
)),
|
loc_expr: Located {
|
||||||
vec![(
|
region: Region::new(0, 0, 11, 12),
|
||||||
var_store.fresh(),
|
value: Num(unsafe { Variable::unsafe_test_debug_variable(7) }, 5),
|
||||||
Located {
|
|
||||||
region: Region::zero(),
|
|
||||||
value: Int(var_store.fresh(), 5),
|
|
||||||
},
|
},
|
||||||
)],
|
expr_var: unsafe { Variable::unsafe_test_debug_variable(8) },
|
||||||
CalledVia::Space,
|
annotation: None,
|
||||||
|
}),
|
||||||
|
Box::new(Located {
|
||||||
|
region: Region::zero(),
|
||||||
|
value: Expr::Call(
|
||||||
|
Box::new((
|
||||||
|
unsafe { Variable::unsafe_test_debug_variable(138) },
|
||||||
|
Located {
|
||||||
|
region: Region::zero(),
|
||||||
|
value: Expr::Var(Symbol::INT_EQ_I64),
|
||||||
|
},
|
||||||
|
unsafe { Variable::unsafe_test_debug_variable(139) },
|
||||||
|
)),
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
unsafe { Variable::unsafe_test_debug_variable(140) },
|
||||||
|
Located {
|
||||||
|
region: Region::zero(),
|
||||||
|
value: Var(Symbol::INT_IS_ZERO_ARG),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
unsafe { Variable::unsafe_test_debug_variable(141) },
|
||||||
|
Located {
|
||||||
|
region: Region::zero(),
|
||||||
|
value: Int(
|
||||||
|
unsafe { Variable::unsafe_test_debug_variable(137) },
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
CalledVia::Space,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
unsafe { Variable::unsafe_test_debug_variable(198) },
|
||||||
|
aliases,
|
||||||
),
|
),
|
||||||
var_store,
|
var_store,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue