Skip to content

Comments

Improve CS9105 in static context#82472

Open
stevenelliottjr wants to merge 1 commit intodotnet:mainfrom
stevenelliottjr:fix/improve-cs9105-static-context
Open

Improve CS9105 in static context#82472
stevenelliottjr wants to merge 1 commit intodotnet:mainfrom
stevenelliottjr:fix/improve-cs9105-static-context

Conversation

@stevenelliottjr
Copy link
Contributor

Fixes #82423

When a primary constructor parameter is referenced from a static member of the same declaring type, the compiler now reports the new CS9360 with the message:

Cannot use primary constructor parameter 'X' in a static member.

instead of the generic CS9105:

Cannot use primary constructor parameter 'int X' in this context.

This follows the same pattern used for extension parameters (ERR_ExtensionParameterInStaticContext, added in #81606) and provides clearer guidance, similar to how CS0026 explicitly calls out static context for this.

What changed

  • New error code: ERR_PrimaryConstructorParameterInStaticContext = 9360
  • Detection: When the containing member is static, not in a parameter default value or attribute argument, and belongs to the same type as the primary constructor
  • Preserved behavior: The generic CS9105 continues to be reported for nested types accessing outer type parameters, non-primary constructors, attribute arguments, and parameter default values

Test plan

  • Updated PrimaryConstructorTests.ParameterScope parametrized test data (8231 test cases, all pass)
  • Updated standalone tests: Initializers_02, Initializers_03, ParameterCapturing_043/044/159, ShadowedByMemberFromBase_21
  • Updated RecordTests.Initializers_02/03, RecordTests.FieldAsPositionalMember_Const
  • Updated RecordStructTests.Initializers_02/03
  • Verified unchanged behavior for nested types (ShadowedByMemberFromBase_22), other constructors (ShadowedByMemberFromBase_23), and attribute arguments

When a primary constructor parameter is referenced from a static member
of the same declaring type, report the new CS9360 error with the message
"Cannot use primary constructor parameter '{name}' in a static member."
instead of the generic CS9105 "Cannot use primary constructor parameter
'{type name}' in this context."

This follows the same pattern used for extension parameters
(ERR_ExtensionParameterInStaticContext) and provides clearer guidance,
similar to how CS0026 explicitly mentions static context for 'this'.

The generic CS9105 continues to be reported for other invalid contexts:
nested types, non-primary constructors, attribute arguments, and
parameter default values.
@stevenelliottjr stevenelliottjr requested a review from a team as a code owner February 20, 2026 03:28
@dotnet-policy-service dotnet-policy-service bot added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Feb 20, 2026
Comment on lines +2090 to +2091
if (this.ContainingMember() is { IsStatic: true } && !InParameterDefaultValue && !InAttributeArgument &&
(object)this.ContainingMember().ContainingSymbol == primaryCtor.ContainingSymbol)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could do something like this to avoid calling ContainingMember() twice (since it seems to do potentially non-trivial work):

Suggested change
if (this.ContainingMember() is { IsStatic: true } && !InParameterDefaultValue && !InAttributeArgument &&
(object)this.ContainingMember().ContainingSymbol == primaryCtor.ContainingSymbol)
if (this.ContainingMember() is { IsStatic: true } containingMember && !InParameterDefaultValue && !InAttributeArgument &&
(object)containingMember.ContainingSymbol == primaryCtor.ContainingSymbol)

@jjonescz jjonescz requested a review from a team February 23, 2026 09:46
{
Error(diagnostics, ErrorCode.ERR_InvalidPrimaryConstructorParameterReference, node, parameter);
// Give a better error for the simple case of using a primary constructor parameter in a static member
if (this.ContainingMember() is { IsStatic: true } && !InParameterDefaultValue && !InAttributeArgument &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!InParameterDefaultValue

Is there a test that fails if condition !InParameterDefaultValue is removed?

{
Error(diagnostics, ErrorCode.ERR_InvalidPrimaryConstructorParameterReference, node, parameter);
// Give a better error for the simple case of using a primary constructor parameter in a static member
if (this.ContainingMember() is { IsStatic: true } && !InParameterDefaultValue && !InAttributeArgument &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!InAttributeArgument

Is there a test that fails if condition !InAttributeArgument is removed?

@AlekseyTs
Copy link
Contributor

Done with review pass (commit 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Community The pull request was submitted by a contributor who is not a Microsoft employee.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve CS9105 in static context

3 participants