Compiler (?) error in zenscript involving local variable types
esotericist opened this issue · 5 comments
Issue Description:
While trying to set up an event-driven marker system for Antique Atlas (using the Antique Atlas Crafttweaker Adapter ), I started experiencing a very opaque error when loading the world.
The more full version of the script was attempting to use the 'thisname' variable in constructing a more meaningful label for the marker, but when I started getting this error, it took me ages to figure out the cause.
What happens:
When line 58 of the script is uncommented, the exception displayed in the log occurs.
With line 58 commented out, this doesn't happen.
The same print statement on line 53 also doesn't cause this problem.
Notably, the only part of the log I can see that indicates a script line number implies the problem is the start of the function. That's not terribly helpful.
What you expected to happen:
Ideally, I'd like for the script to work as expected. As far as I can tell I'm not doing anything that should be problematic.
Script used: https://gist.github.com/esotericist/c478e5a93ed7ac2dd134a24853df40c1#file-antiqueatlas-zs
crafttweaker.log file: https://gist.github.com/esotericist/c478e5a93ed7ac2dd134a24853df40c1#file-crafttweaker-log
Affected Versions (Do not use "latest"):
- Minecraft: 1.12.2
- Forge: 14.23.4.2705
- Crafttweaker: 1.12-4.1.9
- Using a server: no
Your most recent log file where the issue was present:
https://gist.github.com/esotericist/c478e5a93ed7ac2dd134a24853df40c1#file-latest-log
I'm not in a position to try that right now, but if it helps, that is definitely indicative of a compiler error.
The code as structured should never do anything with the variable in question in any case other than it having a value, since that block only gets called when issample == true
, which is only set in the same block where thisname
is given a value.
I had an opportunity to try it, and yes, initializing the variable with ""
does help, but that still shows there's definitely a problem in the compiler, since previous (failing) versions of the script were initializing the variable immediately before use (instead of initializing in a different block). I mostly have the current arrangement because it demonstrates the problem (and when it doesn't occur).
I can take a look into it when I get the time to do so, though in regards of your code initializing the variable is probably the best choice anyway, since then you don't need that boolean flag issample
as you can use if(!thisname.isEmpty)
or if(!isNull(thisName))
depending on the value you initialize it with. This would safe you one local variable in the stack, which can lead to slightly better memory usage and speed.
Okay, here I am again, and checked your code anew:
The issue here is not (entirely) ZS's fault:
ZenScript compiles into Java Code.
In Java Code, there can only be references to definitely assigned variables, which is something your code violates.
You are correct in the way that the variable will only ever be called if there is a value assigned to it, but that is something the code checking algorithm cannot foresee.
If I wanted to write the same in plain Java, I would get the following error (which would prevent me from even compiling):
If you checked the JLS 4.12.5. Initial Values of Variables:
A local variable (§14.4, §14.14) must be explicitly given a value before it is used, by either initialization (§14.4) or assignment (§15.26), in a way that can be verified using the rules for definite assignment (§16 (Definite Assignment)).
So, the issue is in your code, not in ZS.
You are correct, this is something ZS should catch, but that would require an internal rewrite of some stuff that should not be changed within a version release.