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

Stray semicolon above namespace keyword causes warning CS7022 and unexpected exit #53472

Closed
OoLunar opened this issue May 14, 2021 · 7 comments · Fixed by #54385
Closed

Stray semicolon above namespace keyword causes warning CS7022 and unexpected exit #53472

OoLunar opened this issue May 14, 2021 · 7 comments · Fixed by #54385
Assignees
Milestone

Comments

@OoLunar
Copy link

OoLunar commented May 14, 2021

Description

Expected behavior:
Either compiler error to be thrown or for everything to run as expected without a sudden exit.

Actual behavior:
Having a stray semicolon above the namespace keyword causes CS7022. A reproducable example is below:

using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
; // This will cause CS7022

namespace Tomoe.Commands.Public {

This can be placed in any C# file, and the runtime warning will occur, causing the program to suddenly exit with code 0. Opening up the debugger, it seems it exits right after System.Runtime.dll loads. It seems several people over on this StackOverflow Answer have also been having this issue.

Configuration

.NET version: 5.0.202
OS: Windows 10 and Ubuntu 20.04
Arch: x64
Specific to configuration: Untested.

Regression?

Haven't thoroughly tested. On .netcore3.1 in Visual Studio, a syntax error is thrown with the following message: Feature "top-level statements" is not available in C# 8. Please use language version 9 or higher

Other information

I start the program, I get the warning, then it suddenly exits with code 0. Yes, the same behaviour happens when I'm in Gnome Terminal (Ubuntu) or Windows Terminal/Powershell (Windows 10)
image
image

Simple Solution

Remove stray semicolons. No stack traces will be thrown. A great way to teach fellow peers to always review PR's instead of accepting them blindly.

@mairaw
Copy link
Contributor

mairaw commented May 14, 2021

@jaredpar can you help route this? Is this something we could catch at compile time?

@GrabYourPitchforks GrabYourPitchforks transferred this issue from dotnet/core May 17, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels May 17, 2021
@jaredpar
Copy link
Member

Thanks for taking the time to file this feedback issue. Unfortunately this is not a bug. The language is operating as intended here. The top level semi-colon here is a valid statement in C# and hence is correctly interpreted as such. The warning here is alerting the user that the typical Main method is being ignored because of the presence of top level statements.

This is functioning how the language team intended here.

@jaredpar jaredpar added Resolution-By Design The behavior reported in the issue matches the current design and removed untriaged Issues and PRs which have not yet been triaged by a lead labels May 17, 2021
@OoLunar
Copy link
Author

OoLunar commented May 17, 2021

Pardon me, but you're telling me that it's intentional that the program will exit? These top level semicolons can be littered across several files, and the warning will only be thrown at the file with the Main method. This can lead to several hours wasted because the top level semicolon was in file B, but the main method and warning was in file A

@jaredpar
Copy link
Member

Pardon me, but you're telling me that it's intentional that the program will exit?

It's intentional that the compiler will execute top level statements when defined by the customer. In the case that the customer defines one of the no-op statements (empty statement, uninitialized decl, etc ...) then yes the program will exit after completing them with no visible effect. This is true if you put the same statements in traditional Main methods.

These top level semicolons can be littered across several files, and the warning will only be thrown at the file with the Main method.

Top level statements can only occur in a single file. Using them in multiple files will produce an error.

This can lead to several hours wasted because the top level semicolon was in file B, but the main method and warning was in file A

I agree that there are cases where this can be subtle to detect. At the same time the it's not desirable for the compiler to emit warnings here. Consider why would the compiler emit a warning here but not emit a warning with the Main method had a single statement that was a semi-colon?

static void Main() { 
    ;
}

This is just as wrong in that it immediately exits yet the compiler doesn't give a diagnostic. There are also a host of other statements for which there is an immediate exit (unused decls for example). The principal here is that we treat top level statements essentially as if they were typed in the Main method itself and give equivalent diagnostics for them.

@OoLunar
Copy link
Author

OoLunar commented May 18, 2021

Ah, that makes a lot more sense now. Thank you for the very thorough explanation.

@SJFriedl
Copy link

This feels like it violates the Principle of Least Surprise, and that treating

using My.Library;; // note two semicolons

the same as a customer intended to create an empty null block is going to have a lot of people - including those in this thread - just burn a bunch of time.

It's too bad that this special case - a single stray semicolon at the top level - can't trigger a slightly more specific diagnostic, because that single semicolon, though legal in the language, is going to be a typo far more often than it will be intentional. Of course, resolvable by Bingling, but it doesn't seem like it should be necessary.

"The best tech support is that which is not needed" - me

@jcouv jcouv reopened this Jun 23, 2021
@jcouv
Copy link
Member

jcouv commented Jun 23, 2021

Re-opening as LDM decided to make it an error if all top-level statements are empty.

@jcouv jcouv self-assigned this Jun 23, 2021
@jcouv jcouv removed the Resolution-By Design The behavior reported in the issue matches the current design label Jun 23, 2021
@jcouv jcouv added this to the 17.0 milestone Jun 23, 2021
@jcouv jcouv added the help wanted The issue is "up for grabs" - add a comment if you are interested in working on it label Jun 23, 2021
@AlekseyTs AlekseyTs self-assigned this Jun 23, 2021
@jcouv jcouv removed their assignment Jun 23, 2021
@jcouv jcouv removed the help wanted The issue is "up for grabs" - add a comment if you are interested in working on it label Jun 23, 2021
AlekseyTs added a commit to AlekseyTs/roslyn that referenced this issue Jun 25, 2021
AlekseyTs added a commit that referenced this issue Jun 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants