-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Fix inconsistent duplicate modifier error reporting #80880
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
Conversation
…declarations Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
| // Check for duplicate modifiers in local declarations. | ||
| // We call ToDeclarationModifiers here only to report duplicate modifier errors. | ||
| // The actual modifier (const) is determined by node.IsConst below. | ||
| _ = node.Modifiers.ToDeclarationModifiers(isForTypeDeclaration: false, diagnostics.DiagnosticBag ?? new DiagnosticBag()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot does the compiler use new DiagnosticBag() or something like DiagnosticBag.Discarded instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to use a null-conditional check if (diagnostics.DiagnosticBag is { } bag) instead of ?? new DiagnosticBag(). This avoids creating an unnecessary DiagnosticBag instance when diagnostics are being discarded. Commit: 90220cc
src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalErrorTests.cs
Outdated
Show resolved
Hide resolved
| { | ||
| // Duplicate modifiers for local declarations and local functions should not produce | ||
| // parsing errors. They will be reported during binding. | ||
| var localDeclaration = @" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot use raw string literals for tests please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converted test strings to raw string literals. Commit: 025f321
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
|
@copilot please assess failing tests in LocalFunctionParsingTests and determine what needs to happen. |
…tations Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Fixed 4 failing tests in LocalFunctionParsingTests (DuplicateAsyncs1-4). These tests were expecting both ERR_TypeExpected and ERR_DuplicateModifier errors, but with the change to report duplicate modifiers only during binding, they now correctly expect only ERR_DuplicateModifier. The parsing-only tests (UsingDeclaration calls) now expect no errors. All 26 LocalFunctionParsingTests now pass. Commit: c5cd652 |
| // (6,33): error CS1031: Type expected | ||
| // async async async async async void F() { } | ||
| Diagnostic(ErrorCode.ERR_TypeExpected, "async").WithLocation(6, 33)); | ||
| UsingDeclaration(text, options: TestOptions.Regular9); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot for any tests you updated where there is now no more syntactic diagnostics, add a semantic test that validates that it still fails to compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added DuplicateModifiers_StillFailDuringBinding test that validates duplicate modifiers still produce compilation errors (CS1004) during binding for local declarations, local functions, and type declarations. The DuplicateAsync and DuplicateStatic tests already had semantic validation via CreateCompilation().VerifyDiagnostics() calls. Commit: f552b35
…inding Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
|
@dotnet/roslyn-compiler ptal. |
| // The actual modifier (const) is determined by node.IsConst below. | ||
| if (diagnostics.DiagnosticBag is { } bag) | ||
| { | ||
| _ = node.Modifiers.ToDeclarationModifiers(isForTypeDeclaration: false, bag); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this does a number of things we don't want here. We don't need any of the logic that it has for calculating method accessibility, we don't want to report ERR_PartialMisplaced for locals here, etc. I would expect this to be more targeted, why can't the change just be reporting a different error in LanguageParser in the deleted section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A goal i personally have here is to not report syntax errors when htere is no problem fitting the user code to the syntax model (as per some of the design docs we have for this area). I'd prefer this be in the binder, with the code properly written to do the right amount of appropriate checking. So i'm definitely open to tweaking it at the binder to not do unnecessary thigns.
I could move back into the parser. but i would still prefer to avoid that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with saving the errors until binding if that's part of the goal of the PR. But I definitely don't think we want all the logic in ToDeclarationModifiers today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@333fred Tht works for me. I'll move this to draft and investigate more a good way to do the checking in the binding phase.
Summary
This PR fixes issue #32106 - inconsistent duplicate modifier error reporting.
Problem: Duplicate modifiers were reported differently depending on declaration type:
Solution: Removed parser check, added binder check for local declarations to unify behavior.
Result: All duplicate modifiers now consistently report CS1004 during binding, with no parsing errors.
Changes
Files Modified: 4 files, +42 insertions, -54 deletions
Parser (
LanguageParser.cs): -5 lines, +3 comment linesBinder (
Binder_Statements.cs): +5 linesToDeclarationModifiers()for duplicate checkingTests (
LexicalErrorTests.cs,LocalFunctionParsingTests.cs): +76, -52 linesDuplicateModifiers_NotReportedDuringParsingusing raw string literalsDuplicateModifiers_StillFailDuringBindingto validate semantic errorsVerification
✅ All Tests Pass:
✅ Security: CodeQL check passed
✅ Code Review: All feedback addressed
Before/After Comparison
public public class Cconst const int astatic static void F()async async void F()All duplicate modifiers now handled uniformly during binding phase.
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.