ID:2698162
 
Not a bug
BYOND Version:above 514.1548
Operating System:Windows 10 Home 64-bit
Web Browser:Chrome 91.0.4472.124
Applies to:Dream Maker
Status: Not a bug

This is not a bug. It may be an incorrect use of syntax or a limitation in the software. For further discussion on the matter, please consult the BYOND forums.
Descriptive Problem Summary:

initial(typath.vars["a_var_name"]) is runtiming on versions above 514.1548, this worked without issues before

Numbered Steps to Reproduce Problem:

See code

Code Snippet (if applicable) to Reproduce Problem:
/datum/a
var/bloop = "a bloop"

var/datum/a/datum_typepath = /datum/a

world.log << initial(datum_typepath.vars["bloop"])


Expected Results:

you get "a bloop"

Actual Results:

runtime error: Cannot read /datum/a (/datum/a).vars
proc name: New (/a/New)
usr: null
src: /a (/a)
call stack:
/a (/a): New()

Does the problem occur:
Every time? Or how often? yes
In other games? yes
In other user accounts? yes
On other computers? yes

When does the problem NOT occur?

never

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked?

514.1548 works for sure, 514.1554 and above runtimes. I wasn't able to pinpoint exactly what version made the change, it's between both of those

Workarounds:

initial(typepath.thevarname) still works fine

Try world.log << initial(datum_typepath.vars)["bloop"]

But, it seems that vars is list, and to read initial list you need to instantiate it, it isn't a string and etc.
In response to _Elar_
_Elar_ wrote:
Try world.log << initial(datum_typepath.vars)["bloop"]

But, it seems that vars is list, and to read initial list you need to instantiate it, it isn't a string and etc.

Yes, vars is a list and you typically can't access those in initialize.

Still, it looks like vars got a pass since it was working before (tgmc codebase on ss13 uses that in a unittest for more than a year now)</<>
vars isn't actually a list

Most built-in variables that use lists are actually special objects.

The easiest way to see this in action is to look at the \ref of the "list"s, and compare it to a real list.

The final 6 hex-characters of a \ref string is the things ID, and the remaining 1 or 2 characters are the TypeID. for real lists this is 0x21, for things like overlay, contents, or vars, its some different number.
I'm finally looking into this, but I'm having a very hard time of it without the version being narrowed down further. There were too many changes to track. Unfortunately one thing I can't do is follow the compilation in a working build to see how it should be handling this differently, so I need to be able to tell more specifically what code changes are in play.

[edit]
I just ran a test in 514.1544 since I had that handy, and compiled and ran from there. It didn't work there either. That's earlier than the 514.1548 that you said works. It seems really unlikely that it would suddenly work in 1448, then not in some version after that. Sounds more like maybe the issue occurred earlier than you thought, and when you thought you tested 514.1548 it was actually a different build.
Allright, so more news on this.

the code snippet i sent actually doesn't work on windows since at least 513.1539, if it ever worked.

We are using initial(typath.vars["a_var_name"]) in our unit test, which are run on linux; I don't have linux installed on my computer, so i can't test it myself exactly.

So what i an say:
Our unit tests ran on linux until 514.1548
above that, we have a runtime
I have never seen it work on windows
I have not ran the code myself on a linux computer, but i'm 80% confident that the issue comes from the different OS (i've checked and checked again with our ci, it's really the same code that in my windows test environment)

There's no way this code would work on Linux but not on Windows. It's not that sort of issue. There are certain issues where you might expect a little oddness or inconsistency between systems, but this isn't one of them.

I ran through this thoroughly in the debugger, and the issue is that there's never any actual list to read the var from. All indications are that this code never worked, and if it ever did it 1) would have worked the same on Linux or Windows, and 2) would have stopped because of some identifiable change in how the compiler handles initial() or how the runtime interpreter reads it.

There is no change in 1548. I went through everything that could possibly relate to this and there's nothing that would explain the issue. But since the code doesn't work in older builds in Windows, it doesn't work in Linux in those builds either.

So if the code ever worked, you're gonna have to go way back to narrow down where it stopped. My belief is that it never did, since there's no list concept to cover this, which is also why it's not something I can easily change as a feature request. Rather, I think this points to a flaw in your unit tests where they appeared to pass for some reason but didn't really. If however you can narrow down a version where this code in isolation positively worked, and then didn't, then I should theoretically be able to find the change that made it stop and use that to see if I can change the behavior going forward.
So for the record, initial(a.var[b]) is supposed to runtime at all time if a is a typath.

however, if c is a list of typepath, then initial(c[1].vars[b]) was not runtiming, and was actually working fine.

The compiler was probably not understanding that c[1] was a typepath; this was "fixed" around 1548, hence the bug report.
Lummox JR resolved issue (Not a bug)
It looks from the release notes like the fix was probably in 1550 or 1552. It seems that the chaining operators were incorrect in some edge cases like this ones, and it was interacting in a weird way with initial().