Improve error message for record inheritance without parameter list#80795
Improve error message for record inheritance without parameter list#80795CyrusNajmabadi merged 28 commits intomainfrom
Conversation
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
| ); | ||
| } | ||
|
|
||
| [Fact] |
There was a problem hiding this comment.
@copilot add WorkItem attributes to all the tests you added. Use raw string literals for all test cases. Do not place the final close paren of the Verify Diagnostics call on a new line. #Closed
There was a problem hiding this comment.
@copilot update the switch in src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs to fix the compiler error.
There was a problem hiding this comment.
Done. Added WorkItem attributes, converted to raw string literals, fixed formatting, and updated ErrorFacts.cs switch in commit a8c6b5a.
There was a problem hiding this comment.
Done. Updated the switch in ErrorFacts.cs to include ERR_UnexpectedArgumentListInBaseTypeWithoutParameterList in commit a8c6b5a.
…, fix formatting, and update ErrorFacts switch Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
| Diagnostic(ErrorCode.ERR_UnexpectedArgumentListInBaseTypeWithoutParameterList, "(1)").WithArguments("R2").WithLocation(2, 15)); | ||
| } | ||
|
|
||
| [Fact] |
There was a problem hiding this comment.
@copilot please merge the [Fact, WorkItem(...)] pieces.
Also, please add tests that validate coverage for the checks you included for TypeKind.Class and TypeKind.Interface #Closed
There was a problem hiding this comment.
Done. Merged attributes to single line format [Fact, WorkItem(...)] and added three tests for coverage: StructWithArgumentListInBaseType (validates TypeKind != Class), RecordStructWithArgumentListInBaseType (validates record struct), and RecordWithArgumentListToInterface (validates baseType.TypeKind == Interface). All tests pass. Commit 3e8f2a1.
… interface scenarios Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
| { | ||
| diagnostics.Add(ErrorCode.ERR_UnexpectedArgumentList, primaryConstructorBaseType.ArgumentList.Location); | ||
| var typeDecl = (TypeDeclarationSyntax)decl.SyntaxReference.GetSyntax(); | ||
|
|
There was a problem hiding this comment.
@copilot lines cannot be blank. Fix this line, and add a note to the contributing guidelines emphasizing this. #Closed
There was a problem hiding this comment.
Fixed. Removed the blank line from SourceNamedTypeSymbol_Bases.cs line 644 and added a guideline to CONTRIBUTING.md stating "DO NOT use blank lines (lines with only whitespace). Ensure all lines either have content or are completely empty." Commit 8f9d4c2.
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
| var typeDecl = (TypeDeclarationSyntax)decl.SyntaxReference.GetSyntax(); | ||
|
|
||
| // Check if this is a class inheriting from a class but missing a parameter list | ||
| if (TypeKind == TypeKind.Class && |
There was a problem hiding this comment.
@copilot this line ends with a trailing space (as do several others). Fix this to not have the trailing space. Also update the copilot instructions to state that trailing spaces and blank lines must be avoided. #Closed
There was a problem hiding this comment.
Fixed. Removed all trailing spaces from SourceNamedTypeSymbol_Bases.cs and added guideline to .github/copilot-instructions.md under Key Conventions: "Code Formatting: Avoid trailing spaces and blank lines (lines with only whitespace). Ensure all lines either have content or are completely empty." Commit 4a7e9f3.
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
| if (isClassInheritingFromClass) | ||
| { | ||
| comp.VerifyDiagnostics( | ||
| // (3,5): error CS9339: Cannot pass arguments to the base type without a parameter list on the type declaration. Consider adding an empty parameter list to 'Point'. |
There was a problem hiding this comment.
The error is now:
// (3,5): error CS9343: Cannot pass arguments to the base type without a parameter list on the type declaration.
// Base()
Which i think is reasonable, regardless of lang version. The code is def in error no matter what, but the primary error (to me) is the use of () on the base-list without a parameter list on the type. Now, if you were to add such a parameter list (removing this error), you'd have the secondary error mentioning you need the right lang version.
This flow makes sense to me and balances error messages and ordering.
src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol_Bases.cs
Outdated
Show resolved
Hide resolved
| // Check if this is a class inheriting from a class but missing a parameter list | ||
| if (TypeKind == TypeKind.Class && | ||
| baseType.TypeKind != TypeKind.Interface && | ||
| decl.SyntaxReference.GetSyntax() is TypeDeclarationSyntax { ParameterList: null }) |
There was a problem hiding this comment.
decl.SyntaxReference.GetSyntax() is TypeDeclarationSyntax { ParameterList: null }
There is absolutely no need to rewrite this with a pattern. In fact, we want to use cast because, unlike a pattern, it doesn't fail silently. So, while working under Compilers, please, stop rewriting conditions to use patterns due to personal stylistic preference. Changes like that aren't welcome unless you intend to change behavior. #Closed
There was a problem hiding this comment.
And I mean behavior of the expression that is getting switched to a pattern
There was a problem hiding this comment.
this was intentional as the code in SourceNamedTypeSymbolBase seems to indicate that it can support BaseTypeDeclarationSyntax so i didn't want to blindly cast. I couldn't prove to myself that even if TypeKind was .Class that this was a guarantee. So it made sense to me to write it this way.
If you're sure that this is an invariant, and should crash otherwise, i'm happy to change. But this was not a 'style' choice. This was intentional checking, and would have been done, even without a pattern as i thought aactually validating possible cases was appropriate given how many symbols/etc. in the compiler layer can wrap varying underlying syntax constructs.
There was a problem hiding this comment.
If you're sure that this is an invariant
There is absolutely no need to worry about that in context of this PR because the original conditions can be evaluated in the same order and with the same short-circuiting logic. Therefore, there is absolutely no need to change them in this PR
|
Done with review pass (commit 17) #Closed |
Fixes #48243
Summary
Successfully improved the compiler error message for records and classes that attempt to pass arguments to their base type without having a parameter list.
Before:
After:
Example:
Problem code:
Fix:
The new error message provides clear guidance on what's wrong and how to fix it.
PR Feedback Addressed
💡 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.