mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 03:42:17 +00:00
Handle simple aliased fn in params value def
This commit is contained in:
parent
6cffe9b1db
commit
36df43fadc
6 changed files with 77 additions and 29 deletions
|
@ -751,6 +751,9 @@ mod cli_run {
|
||||||
App1.getCompanies [1, 2]: ["https://api.example.com/one/companies/1", "https://api.example.com/one/companies/2"]
|
App1.getCompanies [1, 2]: ["https://api.example.com/one/companies/1", "https://api.example.com/one/companies/2"]
|
||||||
App2.getCompanies [3, 4]: ["http://api.example.com/two/companies/3", "http://api.example.com/two/companies/4"]
|
App2.getCompanies [3, 4]: ["http://api.example.com/two/companies/3", "http://api.example.com/two/companies/4"]
|
||||||
App2.getCompanies [5, 6]: ["http://api.example.com/two/companies/5", "http://api.example.com/two/companies/6"]
|
App2.getCompanies [5, 6]: ["http://api.example.com/two/companies/5", "http://api.example.com/two/companies/6"]
|
||||||
|
App1.getPostAliased 1: https://api.example.com/one/posts/1
|
||||||
|
App2.getPostAliased 2: http://api.example.com/two/posts/2
|
||||||
|
App3.getPostAliased 3: https://api.example.com/three/posts/3
|
||||||
usersApp1: ["https://api.example.com/one/users/1", "https://api.example.com/one/users/2", "https://api.example.com/one/users/3"]
|
usersApp1: ["https://api.example.com/one/users/1", "https://api.example.com/one/users/2", "https://api.example.com/one/users/3"]
|
||||||
getUserApp3Nested 3: https://api.example.com/three/users/3
|
getUserApp3Nested 3: https://api.example.com/three/users/3
|
||||||
usersApp3Passed: ["https://api.example.com/three/users/1", "https://api.example.com/three/users/2", "https://api.example.com/three/users/3"]
|
usersApp3Passed: ["https://api.example.com/three/users/1", "https://api.example.com/three/users/2", "https://api.example.com/three/users/3"]
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
module { appId, protocol } -> [baseUrl, getUser, getPost, getPosts, getPostComments, getCompanies]
|
module { appId, protocol } -> [
|
||||||
|
baseUrl,
|
||||||
|
getUser,
|
||||||
|
getPost,
|
||||||
|
getPosts,
|
||||||
|
getPostComments,
|
||||||
|
getCompanies,
|
||||||
|
getPostAliased,
|
||||||
|
]
|
||||||
|
|
||||||
## value def referencing params
|
## value def referencing params
|
||||||
baseUrl : Str
|
baseUrl : Str
|
||||||
|
@ -33,3 +41,8 @@ getCompanies = \ids ->
|
||||||
protocol "api.example.com/$(appId)/companies/$(Num.toStr id)"
|
protocol "api.example.com/$(appId)/companies/$(Num.toStr id)"
|
||||||
|
|
||||||
List.map ids getCompany
|
List.map ids getCompany
|
||||||
|
|
||||||
|
## aliasing top-level fn
|
||||||
|
getPostAliased : U32 -> Str
|
||||||
|
getPostAliased =
|
||||||
|
getPost
|
||||||
|
|
|
@ -44,6 +44,9 @@ main =
|
||||||
App1.getCompanies [1, 2]: $(Inspect.toStr (App1.getCompanies [1, 2]))
|
App1.getCompanies [1, 2]: $(Inspect.toStr (App1.getCompanies [1, 2]))
|
||||||
App2.getCompanies [3, 4]: $(Inspect.toStr (App2.getCompanies [3, 4]))
|
App2.getCompanies [3, 4]: $(Inspect.toStr (App2.getCompanies [3, 4]))
|
||||||
App2.getCompanies [5, 6]: $(Inspect.toStr (App2.getCompanies [5, 6]))
|
App2.getCompanies [5, 6]: $(Inspect.toStr (App2.getCompanies [5, 6]))
|
||||||
|
App1.getPostAliased 1: $(App1.getPostAliased 1)
|
||||||
|
App2.getPostAliased 2: $(App2.getPostAliased 2)
|
||||||
|
App3.getPostAliased 3: $(App3.getPostAliased 3)
|
||||||
usersApp1: $(Inspect.toStr usersApp1)
|
usersApp1: $(Inspect.toStr usersApp1)
|
||||||
getUserApp3Nested 3: $(getUserApp3Nested 3)
|
getUserApp3Nested 3: $(getUserApp3Nested 3)
|
||||||
usersApp3Passed: $(Inspect.toStr usersApp3Passed)
|
usersApp3Passed: $(Inspect.toStr usersApp3Passed)
|
||||||
|
|
|
@ -113,21 +113,35 @@ impl Annotation {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert_to_fn(&mut self, argument_count: usize, var_store: &mut VarStore) {
|
pub fn add_arguments(&mut self, argument_count: usize, var_store: &mut VarStore) {
|
||||||
let mut arg_types = Vec::with_capacity(argument_count);
|
match self.signature {
|
||||||
|
Type::Function(ref mut arg_types, _, _) => {
|
||||||
|
arg_types.reserve(argument_count);
|
||||||
|
|
||||||
for _ in 0..argument_count {
|
for _ in 0..argument_count {
|
||||||
let var = var_store.fresh();
|
let var = var_store.fresh();
|
||||||
self.introduced_variables.insert_inferred(Loc::at_zero(var));
|
self.introduced_variables.insert_inferred(Loc::at_zero(var));
|
||||||
|
|
||||||
arg_types.push(Type::Variable(var));
|
arg_types.push(Type::Variable(var));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let mut arg_types = Vec::with_capacity(argument_count);
|
||||||
|
|
||||||
|
for _ in 0..argument_count {
|
||||||
|
let var = var_store.fresh();
|
||||||
|
self.introduced_variables.insert_inferred(Loc::at_zero(var));
|
||||||
|
|
||||||
|
arg_types.push(Type::Variable(var));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.signature = Type::Function(
|
||||||
|
arg_types,
|
||||||
|
Box::new(Type::Variable(var_store.fresh())),
|
||||||
|
Box::new(self.signature.clone()),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.signature = Type::Function(
|
|
||||||
arg_types,
|
|
||||||
Box::new(Type::Variable(var_store.fresh())),
|
|
||||||
Box::new(self.signature.clone()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3135,11 +3135,11 @@ impl Declarations {
|
||||||
Index::push_new(&mut self.function_bodies, loc_function_def);
|
Index::push_new(&mut self.function_bodies, loc_function_def);
|
||||||
|
|
||||||
if let Some(annotation) = &mut self.annotations[index] {
|
if let Some(annotation) = &mut self.annotations[index] {
|
||||||
annotation.convert_to_fn(new_args_len, var_store);
|
annotation.add_arguments(new_args_len, var_store);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((_var, annotation)) = self.host_exposed_annotations.get_mut(&index) {
|
if let Some((_var, annotation)) = self.host_exposed_annotations.get_mut(&index) {
|
||||||
annotation.convert_to_fn(new_args_len, var_store);
|
annotation.add_arguments(new_args_len, var_store);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.declarations[index] = DeclarationTag::Function(function_def_index);
|
self.declarations[index] = DeclarationTag::Function(function_def_index);
|
||||||
|
|
|
@ -12,7 +12,6 @@ use roc_collections::VecMap;
|
||||||
use roc_module::symbol::{IdentId, IdentIds, ModuleId, Symbol};
|
use roc_module::symbol::{IdentId, IdentIds, ModuleId, Symbol};
|
||||||
use roc_region::all::Loc;
|
use roc_region::all::Loc;
|
||||||
use roc_types::subs::{VarStore, Variable};
|
use roc_types::subs::{VarStore, Variable};
|
||||||
use roc_types::types::Type;
|
|
||||||
|
|
||||||
struct LowerParams<'a> {
|
struct LowerParams<'a> {
|
||||||
home_id: ModuleId,
|
home_id: ModuleId,
|
||||||
|
@ -56,12 +55,21 @@ impl<'a> LowerParams<'a> {
|
||||||
|
|
||||||
match tag {
|
match tag {
|
||||||
Value => {
|
Value => {
|
||||||
self.lower_expr(&mut decls.expressions[index].value);
|
let aliasing_fn = self.lower_expr(true, &mut decls.expressions[index].value);
|
||||||
|
|
||||||
if let Some(new_arg) = self.home_params_argument() {
|
if let Some(new_arg) = self.home_params_argument() {
|
||||||
// This module has params, and this is a top-level value,
|
if !aliasing_fn {
|
||||||
// so we need to convert it into a function that takes them.
|
// This module has params, and this is a top-level value,
|
||||||
decls.convert_value_to_function(index, vec![new_arg], self.var_store);
|
// so we need to convert it into a function that takes them.
|
||||||
|
|
||||||
|
decls.convert_value_to_function(index, vec![new_arg], self.var_store);
|
||||||
|
} else {
|
||||||
|
// This value def is just aliasing another function,
|
||||||
|
// we only need to fix the annotation
|
||||||
|
if let Some(ann) = &mut decls.annotations[index] {
|
||||||
|
ann.add_arguments(1, self.var_store);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Function(fn_def_index) | Recursive(fn_def_index) | TailRecursive(fn_def_index) => {
|
Function(fn_def_index) | Recursive(fn_def_index) | TailRecursive(fn_def_index) => {
|
||||||
|
@ -75,25 +83,24 @@ impl<'a> LowerParams<'a> {
|
||||||
.push((var, mark, pattern));
|
.push((var, mark, pattern));
|
||||||
|
|
||||||
if let Some(ann) = &mut decls.annotations[index] {
|
if let Some(ann) = &mut decls.annotations[index] {
|
||||||
if let Type::Function(args, _, _) = &mut ann.signature {
|
ann.add_arguments(1, self.var_store);
|
||||||
args.push(Type::Variable(var))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.lower_expr(&mut decls.expressions[index].value)
|
self.lower_expr(false, &mut decls.expressions[index].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Destructure(_) | Expectation | ExpectationFx => {
|
Destructure(_) | Expectation | ExpectationFx => {
|
||||||
self.lower_expr(&mut decls.expressions[index].value)
|
self.lower_expr(false, &mut decls.expressions[index].value);
|
||||||
}
|
}
|
||||||
MutualRecursion { .. } => {}
|
MutualRecursion { .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_expr(&mut self, expr: &mut Expr) {
|
fn lower_expr(&mut self, is_value_def: bool, expr: &mut Expr) -> bool {
|
||||||
let mut expr_stack = vec![expr];
|
let mut expr_stack = vec![expr];
|
||||||
|
let mut aliasing_fn = false;
|
||||||
|
|
||||||
while let Some(expr) = expr_stack.pop() {
|
while let Some(expr) = expr_stack.pop() {
|
||||||
match expr {
|
match expr {
|
||||||
|
@ -120,8 +127,14 @@ impl<'a> LowerParams<'a> {
|
||||||
}
|
}
|
||||||
Var(symbol, var) => {
|
Var(symbol, var) => {
|
||||||
if let Some((params, arity)) = self.params_extended_home_symbol(symbol) {
|
if let Some((params, arity)) = self.params_extended_home_symbol(symbol) {
|
||||||
|
if is_value_def && arity > 0 {
|
||||||
|
// Aliased top-level function, no need to lower
|
||||||
|
aliasing_fn = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
*expr = self.lower_naked_params_var(
|
*expr = self.lower_naked_params_var(
|
||||||
*arity,
|
arity,
|
||||||
*symbol,
|
*symbol,
|
||||||
*var,
|
*var,
|
||||||
params.whole_symbol,
|
params.whole_symbol,
|
||||||
|
@ -357,17 +370,19 @@ impl<'a> LowerParams<'a> {
|
||||||
| AbilityMember(_, _, _) => { /* terminal */ }
|
| AbilityMember(_, _, _) => { /* terminal */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aliasing_fn
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unique_symbol(&mut self) -> Symbol {
|
fn unique_symbol(&mut self) -> Symbol {
|
||||||
Symbol::new(self.home_id, self.ident_ids.gen_unique())
|
Symbol::new(self.home_id, self.ident_ids.gen_unique())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn params_extended_home_symbol(&self, symbol: &Symbol) -> Option<(&ModuleParams, &usize)> {
|
fn params_extended_home_symbol(&self, symbol: &Symbol) -> Option<(&ModuleParams, usize)> {
|
||||||
if symbol.module_id() == self.home_id {
|
if symbol.module_id() == self.home_id {
|
||||||
match self.home_params {
|
match self.home_params {
|
||||||
Some(params) => match params.arity_by_name.get(&symbol.ident_id()) {
|
Some(params) => match params.arity_by_name.get(&symbol.ident_id()) {
|
||||||
Some(arity) => Some((params, arity)),
|
Some(arity) => Some((params, *arity)),
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
None => None,
|
None => None,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue