Allow multidep enums - #414
Conversation
add full enum info to the abi types
cb9b61e to
29a5700
Compare
|
Are there design documents or something about this way of identifying modules? Have you looked at https://community.simplicity-lang.org/t/nominal-types-and-module-identification-in-simplicityhl/62/3 |
|
Also, in what sense are enums "special"? It seems like we are implementing a half-baked form of nominal typing for enums, and only enums. For example using the |
|
I think @KyrylR can give a better answer to the question "why are enums special." Regarding the module system: it currently supports inline mod, but it doesn't support importing a whole moduleб only individual items out of one (functions, type aliases, and enums). So something like this doesn't currently work: mod A {
pub mod B {
pub fn smth() {}
}
}
use crate::A::B;
use B::smth; // error
fn main() {}But we can get On @stringhandler's main question, about single-file and multi-file programs having an exact equivalent, I think yes, and that's the main reason flattening exists at all (#337, more detailed in linked issue). To show it concretely rather than just assert it: I compiled both of the following programs, and they produce the identical CMR: fn add_32(a: u32, b: u32) -> u32 {
let (_, res): (bool, u32) = jet::add_32(a, b);
res
}
fn main() {
let a: u32 = witness::A;
let b: u32 = witness::B;
let c: u32 = witness::C;
assert!(jet::eq_32(c, add_32(a, b)));
}And: mod X {
pub fn add_32(a: u32, b: u32) -> u32 {
let (_, res): (bool, u32) = jet::add_32(a, b);
res
}
}
use crate::X::add_32;
fn main() {
let a: u32 = witness::A;
let b: u32 = witness::B;
let c: u32 = witness::C;
assert!(jet::eq_32(c, add_32(a, b)));
}Both give CMR |
|
Get back to enums. Regarding their usage in std (u32_conver_test.simf), simplicity-lending, and price-oracle, it would be much more convenient and optimized to use enums instead of custom match branching |
It's not, because it creates behavior that we need to maintain, doesn't make sense to users, and which will be difficult to shoehorn into a properly-designd system. I don't think we should keep grafting ad-hoc extensions onto the existing enum implementation, nor onto the existing module system. We should fix the types and module systems properly. |
|
I have no particular opinion about the architectural/design question here, but I just wanted to mention that the issue that this solves is blocking a new Simplex demo that I made based on I can confirm from testing that this PR does effectively remove that limitation in Simplex, and so, with other minor Simplex changes, it would unblock my demo. I would love to see some solution to this issue land in SimplicityHL so that I could publish that new demo as part of Simplex (it's a lot more sophisticated than the existing We've already been building various examples on the |
|
The PR description, at least, should have some description of the issue it solves. |
Updated the description |
|
May I suggest "Fix: enums can't appear in modules" as a PR title? |
|
I think I would prefer holding off on this fix until we have a firm direction in the community forum post. Is it possible to change Simplex's way of doing things? |
Sure |
Yep, I have tried to implement nominal typing for enums, though there are quite a few nuances with imports that prevented doing it with deps support from the beginning Casting was also tough to deal with, so to keep the scope of original PR manageable, I have decided to postpone it I am happy to start/continue the discussion on the forum this week |
Simplex compiles through On maintaining the behavior: enums are currently an unstable feature, same as modules, so nothing here is a commitment. If we'd still rather wait, that's fine by me, but it means enums stay unusable in Simplex until the thread settles, and @schoen's |
Problem
enumcannot be used in any program that the driver wraps in a module, which isevery program, since flattening wraps the entry file too. Two checks reject the
declaration:
parse::Module::validaterejectsenuminside amodblock, andforbid_enum_dec_in_depsrejectsenumin a dependency file. Both exist because anenum's identity in the ABI was its bare declared name, which forced the name to be
unique program-wide.
This blocks
enumin Simplex entirely, and in any multi-fileprogram.
Fix
The ABI no longer identifies an enum by its bare name. It identifies it by the path of
the file the enum was declared in, the module chain inside that file, and the full
expanded type.
The path is what makes this work across dependencies, so a consumer knows which file an
enum comes from.
Previous abi for
last_will.simffile:AbiMeta { witness_types: WitnessTypes({TemplateProgramWitness { inner: Witness("ACTION") }: Action}), param_types: Parameters({}) }Current:
AbiOutput { witness_types: {"ACTION": "<path>(::<modules>): Action { Inherit([u8; 64]), ColdSpend([u8; 64]), HotSpend([u8; 64]) }"}, param_types: {} }The
<modules>segment is omitted when the enum is declared at the top level of itsfile; the driver-assigned
unit_Nwrapper is never shown.