sourcepawn icon indicating copy to clipboard operation
sourcepawn copied to clipboard

Nail down enum structs in natives

Open asherkin opened this issue 3 years ago • 4 comments

Trying to use an enum struct type parameter in a native declaration is a clear compile error:

error 135: cannot use enum struct type "Test" in natives

A number of plugins have started using any[] in their natives to accept enum structs defined in their includes, then casting it back to the struct type in the native handler to work around this.

This is obviously not allowed by the semantics of any[], but it is hard for people to know that - there is no way for the compiler to warn against it (as any is the escape hatch from that!), and it propagates quickly through the community as it makes things appear to work fine.

Forbidding the coercion to any[] again is probably not viable, it is too important to be able to pass them to the truly opaque data structures like ArrayList, but it seems that it would be good to do something here to stop a large number of plugins having a nasty surprise in the future.

No idea what the best path forward here is (if any), as it probably depends on future spcomp plans - the two obvious options I can think of are:

  • Just allow it, using the type name - vow to never change the layout again without some opt-in mechanism.
  • Randomize the order of enum struct fields at compile time - so it very obviously does not work (but data structures will be fine).

Additionally, it looks like they weren't forbidden in forward declarations, which has all the same problems.

See the usage of stylesettings_t in https://github.com/shavitush/bhoptimer/blob/590b70dd2fe3cdb208d5e411fca689134266c78f/addons/sourcemod/scripting/include/shavit.inc, one native handler: https://github.com/shavitush/bhoptimer/blob/590b70dd2fe3cdb208d5e411fca689134266c78f/addons/sourcemod/scripting/shavit-core.sp#L1818-L1826

asherkin avatar Mar 06 '21 11:03 asherkin

This is definitely something that needs to be addressed, thanks for formalizing an issue about this. Inaction here will only make this smellier.

Given the circumstance I believe it’s best to lock the existing internal structure of enum structs. Any further development into enum structs is probably going to find a better home as a revamp of the struct keyword, which would be an excellent opt-in as asherkin mentioned.

Headline avatar Mar 06 '21 11:03 Headline

Related #464

peace-maker avatar Mar 12 '21 23:03 peace-maker

This is intentional, and it was a snap decision I made when doing enum structs. Allowing them to pass through natives when we don't have a clear native API for them seemed like a mistake. And forcing a new API would mean not being able to use existing natives that take any[], of which there are a lot.

The obvious problem with this is that, let's say in the far-flung future, any is a proper dynamically typed value. How do you flatten a struct into an array of anything? Probably at that point we have to abandon any pretense of any being dynamically typed.

dvander avatar Jul 04 '21 03:07 dvander

My vote would be to acknowledge that they're "enum structs". They codify an existing, well-known, syntactically-bad but semantically-ok concept we've had for ages. Thus we allow them in natives and the binary layout becomes part of their API.

Then we save the RTTI stuff for when they become just "structs".

Happy to hear other thoughts.

dvander avatar Jul 04 '21 03:07 dvander