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

Support declaration and consumption of user-defined Unsigned Right Shift operator. #60616

Merged

Conversation

AlekseyTs
Copy link
Contributor

@AlekseyTs AlekseyTs commented Apr 7, 2022

@AlekseyTs
Copy link
Contributor Author

@jcouv, @333fred, @dotnet/roslyn-compiler Please review.

1 similar comment
@AlekseyTs
Copy link
Contributor Author

@jcouv, @333fred, @dotnet/roslyn-compiler Please review.

@jcouv jcouv self-assigned this Apr 8, 2022
@AlekseyTs
Copy link
Contributor Author

@jcouv, @333fred, @dotnet/roslyn-compiler Please review.

@jcouv
Copy link
Member

jcouv commented Apr 8, 2022

Looking

throw null;
}

public static int operator >>(C4 x, int y)
Copy link
Member

@jcouv jcouv Apr 8, 2022

Choose a reason for hiding this comment

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

Consider adding a positive case for parameters being nullable: public static int operator >>>(S1? x, int? y) #Closed

result &= CheckFeatureAvailability(node, MessageID.IDS_FeatureCheckedUserDefinedOperators, diagnostics);
Debug.Assert((methodOpt.Name == WellKnownMemberNames.UnsignedRightShiftOperatorName) == isUnsignedRightShift);

if (Compilation.SourceModule != methodOpt.ContainingModule)
Copy link
Member

@jcouv jcouv Apr 8, 2022

Choose a reason for hiding this comment

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

I didn't understand why the unsigned right shift operator LangVer check is conditioned on resolved method being in source. I would have expected an unconditional LangVer diagnostic for >>> where ever the best signature is found. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't understand why the unsigned right shift operator LangVer check is conditioned on resolved method being in source. I would have expected an unconditional LangVer diagnostic for >>> where ever the best signature is found.

  1. This logic is not new
  2. If the operator is declared in the same module (note, not just in source), we perform the check on the declaration and report the error, if needed. Reporting the same error at every consumption site would only add more noise.

@@ -1037,6 +1037,8 @@ CurrentToken.Kind is (SyntaxKind.GreaterThanToken or SyntaxKind.GreaterThanEqual
operatorToken.Text + operatorToken2.Text + operatorToken3.Text,
operatorToken.ValueText + operatorToken2.ValueText + operatorToken3.ValueText,
operatorToken3.GetTrailingTrivia());

operatorToken = CheckFeatureAvailability(operatorToken, MessageID.IDS_FeatureUnsignedRightShift, forceWarning: true);
Copy link
Member

@jcouv jcouv Apr 8, 2022

Choose a reason for hiding this comment

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

nit: Why do a parser LangVer check as opposed to add check in Binder_Cref? #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why do a parser LangVer check as opposed to add check in Binder_Cref?

Just following the established pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that these are warnings, not errors

@@ -358,6 +358,7 @@ private void CheckOperatorSignatures(BindingDiagnosticBag diagnostics)

case WellKnownMemberNames.LeftShiftOperatorName:
case WellKnownMemberNames.RightShiftOperatorName:
case WellKnownMemberNames.UnsignedRightShiftOperatorName:
Copy link
Member

@jcouv jcouv Apr 8, 2022

Choose a reason for hiding this comment

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

nit: consider updating comment in CheckShiftSignature (add >>>) #Closed

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Done with review pass (iteration 2)

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 2)

@AlekseyTs
Copy link
Contributor Author

@333fred, @dotnet/roslyn-compiler For the second review.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 3)

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

Done review pass (commit 3)

@@ -2311,7 +2317,7 @@ private BoundExpression BindIncrementOperator(CSharpSyntaxNode node, ExpressionS
/// <summary>
/// Returns false if reported an error, true otherwise.
/// </summary>
private bool CheckConstraintLanguageVersionAndRuntimeSupportForOperator(SyntaxNode node, MethodSymbol? methodOpt, TypeSymbol? constrainedToTypeOpt, BindingDiagnosticBag diagnostics)
private bool CheckConstraintLanguageVersionAndRuntimeSupportForOperator(SyntaxNode node, MethodSymbol? methodOpt, bool isUnsignedRightShift, TypeSymbol? constrainedToTypeOpt, BindingDiagnosticBag diagnostics)
Copy link
Member

@333fred 333fred Apr 11, 2022

Choose a reason for hiding this comment

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

Consider just passing the operator kind, and letting the "is unsigned right shift" logic be contained within this method, rather than needing to be specified by a caller. #WontFix

// PROTOTYPE(UnsignedRightShift): This code was previously allowed. Confirm that we are Ok with this
// breaking change and document it.
compilation1.VerifyDiagnostics(
// (9,40): error CS0571: 'C1.operator >>>(C1, int)': cannot explicitly call operator or accessor
Copy link
Member

@333fred 333fred Apr 11, 2022

Choose a reason for hiding this comment

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

Would it be worth adding a version of this test without the specialname flag in the IL? #Pending

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would it be worth adding a version of this test without the specialname flag in the IL?

A method like that can be defined in plain C#.

}

static C1? Test1(C1? x, int? y) => x >>> y;
static C1? Test2(C1? x, int? y) => x >> y;
Copy link
Member

@333fred 333fred Apr 11, 2022

Choose a reason for hiding this comment

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

Unused? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unused?

I think it is used for IL comparison

return x;
}

static C1? Test2(C1? x, int? y)
Copy link
Member

@333fred 333fred Apr 11, 2022

Choose a reason for hiding this comment

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

Unused? #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unused?

Used for IL comparison

@AlekseyTs AlekseyTs merged commit a71a5cf into dotnet:features/UnsignedRightShift Apr 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants