-
-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Zero arg syntax #7529
base: main
Are you sure you want to change the base?
Zero arg syntax #7529
Conversation
Can you post the compiler errors and/or runtime errors you are getting? |
I'd probably suggest adding some |
I added two very basic |
The simplest test:
|
The above seems closer to the real problem, but there are plenty of alias analysis problems as well. Here's one from a
|
Did you try running this with |
The error is definitely coming from Morphic |
The relevant part of the program that fails:
|
It seems this is interesting: Let(
`#UserApp.var`,
Struct(
[],
),
InLayout(
23,
),
Ret(
`#UserApp.var`,
),
),
``` |
There would be a |
Here's the value def coming into can:
|
After canonicalizing the pending_value_def:
|
I think that creates/compiler/mono/src/ir.rs:8179 is an interesting thing to checkout. We apparently create a closure for imported functions (that have no fields because there is no capture needed). And then we don't do normal things with that closure afterwards (like call the function with it) |
But I have no idea. Somewhere this gets changed and I can't find it |
So I've tracked this down to what should be obvious, the layout representation for the lambda set is Struct, with zero fields. But I need to see what's different about have a single arg to figure out what we aren't doing. |
After edited your example so that the function called from main has a single arg and comparing the output, I see this. mono/src/ir.rs (call_by_name_help): } else if field_symbols.is_empty() { // <- Zero args hits this, it thinks we are just assigning a func/closure to a var
println!("field_symbols is empty");
// this is a case like `Str.concat`, an imported standard function, applied to zero arguments
// imported symbols cannot capture anything
let captured = &[];
debug_assert!(proc_name.no_captures());
construct_closure_data(
env,
procs,
layout_cache,
lambda_set,
proc_name,
captured,
assigned,
hole,
)
} else {
println!("None of the above"); // <- A single arg hits this. it recognizes that this is an actual call.
debug_assert_eq!(
argument_layouts.len(),
field_symbols.len(),
"see call_by_name for background (scroll down a bit), function is {proc_name:?}",
);
let field_symbols = field_symbols.into_bump_slice();
let call = self::Call {
call_type: CallType::ByName {
name: proc_name,
ret_layout,
arg_layouts: argument_layouts,
specialization_id: env.next_call_specialization_id(),
},
arguments: field_symbols,
};
let result = build_call(env, call, assigned, ret_layout, hole);
let iter = loc_args.into_iter().rev().zip(field_symbols.iter().rev());
assign_to_symbols(env, procs, layout_cache, iter, result)
} |
An in-progress change for my work to support zero-argument functions in userspace for Roc.