I've the same problem, but only on Windows, and not in a script but a command-line app. Your recent screenshot is from Visual Studio and your first entry contains Target: arm64-apple-macosx13.0. Do both platforms suffer?
The rules around how top-level code is treated are somewhat nuanced:
@main is forbidden in files that allow top-level statements, because the top-level statements provide an implicit entry point.
If you invoke the compiler without any special flags and pass it a single source file, it is treated as top-level code (meaning @main is forbidden; you just write the top-level statements instead). Passing -parse-as-library to the compiler disables this top-level behavior.
If you invoke the compiler without any special flags and pass it multiple source files, all files are treated as library code (top-level statements are forbidden), unless one of the files you pass is named main.swift, in which case the top-level statements in that specific file provide the main function.
IMO, there's not much of an advantage to writing @main explicitly in small single-file scripts; the real power of that attribute is when it's used in a library where some protocol defines the entry point and you just conform to that protocol and get it for free. But clearly folks do want to use it directly even for small scripts, so (in a slight variation to Nate's comment above) I wonder if we'd break compatibility with anything if we just had the frontend use a "deferred main decision" by default and decide whether to allow top-level statements based on whether it detected @main in the file.
Since @main is described in it's proposal A Swift language feature for designating a type as the entry point for beginning program execution. IMO it could be confusing for first timers who are doing some simple googling to test out some Swift, see @main is the latest in how to designate an entry point, then get hit with a somewhat cryptic error when they do.
So yeah, detecting @main and deciding whether to allow top-level statements sounds like a great solution!
It's still not a great situation though, and I'm regularly getting pulled into conversations and questions on it. So, story time!
So. first, the name of the flag is confusing. You have an executable, not a library. It comes from an implementation detail in the C++ parser. There's an enum that tells the parser how it's parsing the file.
A "Library", as far as the parser is concerned, is any normal Swift code. a "Main" swift file is top-level code. -parse-as-library just forces the parser to set the main source file's SourceFileKind to Library instead of Main.
The current heuristic used looks at the number of files and their names. Any single file passed to the parser is given the "Main" SourceFileKind. If more than one file is passed to the compiler, any file with the name "main.swift" will be given the SourceFileKind of "main". It's important to note here that SwiftPM and Xcode both have different heuristics than the compiler, I'm only referring to the compiler.
Okay, so why are we in this mess in the first place? Parsing top-level code and a normal Swift file is different, and the resulting parse trees are not the same. Unfortunately, in order to know whether we have an @main attribute, we have to parse. By the time we know we have an @main, it's too late because we've already parsed incorrectly. I've considered the trade-off of tearing everything down and re-starting the parse in Library mode. The new Swift-Parser work does things differently. I'm hoping that I'll be able to fish the attribute out of the token stream before any ASTs are formed, and make that judgement early.
With the current parser, there's not really a point between the lexing and parsing where I can check before it's too late. The alternative to manually using -parse-as-library would be to tear everything down and restart the compilation when we get it wrong. It's a tradeoff. Maybe the wrong one? To balance things out a bit, I added the note to newer compilers to recommend adding -parse-as-library if the @main is intentional. That way you have some options and aren't just left in the dark.
Hopefully that helps shed some light on what is going on here.
IMO the preferred trade-off would be to emit a warning (instead of an error) with the -parse-as-library recommendation, and then tear things down and reparse as a library anyway. If @main exists, the intent is clear, so the error is just an unpleasant user experience with the tools.