Oh, but how can the following (earlier mentioned) example have anything to do with Script-mode top-level locals being treated as globals?
Create "AnotherFile.swift" containing: func f() -> Int { return a } let a = f() Create "main.swift" containing: print(a) Compile. Run. For ever. At zero % CPU. /Jens On Thu, Sep 22, 2016 at 8:03 PM, Jens Persson <j...@bitcycle.com> wrote: > Thank you for the thorough explanation! > /Jens > > On Thu, Sep 22, 2016 at 7:28 PM, Jordan Rose <jordan_r...@apple.com> > wrote: > >> Yep, it really is a long-standing bug. Script-mode top-level locals are >> treated as globals (module-scope bindings) by the compiler, but their >> initial bindings are evaluated eagerly instead of lazily (as you’d want in >> a script). Taken together, this means that you can get this completely >> unsafe behavior. >> >> So, why is ‘a’ accepted but ‘b’ not in your original example? >> >> func foo() -> Int { return b } >> let a = 1 >> let b = 2 >> print(foo()) >> >> >> The secret to the current behavior is that script mode is executed >> interactively, instead of parsing it all up front. To make things a little >> better, it *actually* parses any number of declarations until it sees >> something it actually needs to execute—a statement or a declaration with an >> initial value expression. This allows for recursive functions while still >> being “live”. >> >> The consequence here is that *one* top-level binding after a series of >> functions may be visible. This is obviously not optimal. >> >> To fix this, we should: >> >> - Distinguish between script-mode top-level locals and module-scope >> variables that happen to be declared. My personal preference is to treat >> anything with explicit access control as a normal lazy global and anything >> without access as a top-level local. >> >> - Consider parsing everything up front, even if we don’t type-check it, >> so that we can say “use of ‘b’ before it’s initialized” instead of >> “undeclared name ‘b’” >> >> Note that we *do* need to be conservative here. This code should >> continue to be rejected, even though ‘f’ doesn’t refer to ‘local’ directly, >> because *calling* ‘f' would be dangerous before the initialization of >> ‘local': >> >> internal func f() -> Int { >> return g() >> } >> *// more code here* >> >> let local = 42 >> private func g() -> Int { >> return local >> } >> >> >> Thanks for bringing this up, if only so I have an opportunity to write >> out the issue. :-) >> Jordan >> >> >> On Sep 21, 2016, at 23:04, Jens Persson <j...@bitcycle.com> wrote: >> >> Did you see the other code examples that came up in that twitter >> conversations? >> For example: >> >> This worrying little program compiles: >> func f() -> Int { >> return a >> } >> let a = f() >> >> >> It also compiles if you print(a) at the end, and it will print 0. >> >> If we replace Int with [Int] it will still compile but crash when run. >> >> And also this: >> >> AnotherFile.swift containing: >> func f() -> Int { >> return a >> } >> let a = f() >> >> main.swift containing >> print(a) >> >> Compile, run (for eternity, at 0% CPU). >> >> /Jens >> >> >> On Thu, Sep 22, 2016 at 3:13 AM, Joe Groff <jgr...@apple.com> wrote: >> >>> >>> > On Sep 21, 2016, at 2:22 PM, Jens Persson via swift-users < >>> swift-users@swift.org> wrote: >>> > >>> > // This little Swift program compiles (and runs) fine: >>> > >>> > func foo() -> Int { return a } >>> > let a = 1 >>> > let b = 2 >>> > print(foo()) >>> > >>> > But if `foo()` returns `b` instead of `a`, I get this compile time >>> error: >>> > "Use of unresolved identifier `b`" >>> >>> This looks like a bug to me (cc-ing Jordan, who's thought about global >>> scoping issues more than me). In "script mode", it shouldn't be possible to >>> refer to a variable before its initialization is executed. However, the way >>> this is currently modeled is…problematic, to say the least, among other >>> reasons because script globals are still visible to "library" files in the >>> same module. >>> >>> -Joe >> >> >> >> >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users