Skip to content
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

generated code from is doesn't valid its usefulness #848

Closed
fperrad opened this issue Nov 4, 2024 · 5 comments · Fixed by #854
Closed

generated code from is doesn't valid its usefulness #848

fperrad opened this issue Nov 4, 2024 · 5 comments · Fixed by #854

Comments

@fperrad
Copy link
Contributor

fperrad commented Nov 4, 2024

Since Lua 5.2, local _ENV = nil is a common idiom which avoids the use of globals.

local type = type
local _ENV = nil

local function bar (v: any)
    if type(v) == 'string' then  -- type is used here
        print(v)
    end
end

return bar

In this second version, type(v) == 'string' is generated from v is string,
but the usefulness of type is not detected.

local type = type  -- unused function type: function(<any type>): string
local _ENV = nil

local function baz (v: any)
    if v is string then  -- hidden use of type
        print(v)
    end
end

return baz
@hishamhm
Copy link
Member

hishamhm commented Nov 4, 2024

The top-level standard library modules (table, string, etc.) are all already auto-localized in the generated code by default. I think a better solution would be to auto-localize standard library global functions as well, so we can all stop writing local type = type and the like once and for all...

@hishamhm
Copy link
Member

hishamhm commented Nov 4, 2024

Also, I wonder what's the practical use of local _ENV = nil in a Teal codebase, since it does already require global annotations for globals and it also reports at compile-time on the use of undeclared variables.

@fperrad
Copy link
Contributor Author

fperrad commented Nov 6, 2024

strict.lua is another way to check the uses of undeclared global variables. It does the same kind of check as tl (appart it works at runtime instead of at compile time).

The idiom local _ENV = nil is different. It forces to localize all used variables in a kind of preamble, with 2 side effects:

  • a small gain of performance
  • it creates a way to modularize with a clear vue of dependencies of each module (and at the end, it prevents to circular dependencies)

So, my point of view is that with tl:

  • strict.lua becomes useless
  • the idiom local _ENV = nil stay useful

@hishamhm
Copy link
Member

I decided to solve this going the other way around, by automatically generating local type = type whenever the is code generates type.

I don't want to make the user code dependent on the knowledge of what happens in the generated code (i.e. so that the fact that is is implemented with type() leaks into the unused variable checking). Doing that could cause weirdness in the future, in case the generated code changes, and then the set of warnings in the user code suddenly changes even though their own code hasn't changed at all.

I'm considering adding a new --gen-compat level called "minimal" that sits between "off" and "optional", that just generates the preambles that do not even try to load compat-5.3. Or maybe this should actually become the new "off"?...

@fperrad
Copy link
Contributor Author

fperrad commented Nov 17, 2024

here, an updated example after #854

local print = print
local _ENV = nil

local function baz (v: any)
    if v is string then  -- attempt to index a nil value (upvalue '_ENV')
        print(v)
    end
end

baz('foo')

the code generated with --gen-compat optional or required run fine.
the code generated with --gen-compat off fails because type is not localized.
and there is no new level minimal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants