-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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 built-in unsigned right shift operators. #60560
Support built-in unsigned right shift operators. #60560
Conversation
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.
Done review pass (commit 1)
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
#nullable disable |
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.
Did I miss a langver test in here? #Resolved
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.
Did I miss a langver test in here?
I haven't touched the lang version part yet.
LiftedULongUnsignedRightShift = Lifted | ULong | UnsignedRightShift, | ||
LiftedNIntUnsignedRightShift = Lifted | NInt | UnsignedRightShift, | ||
LiftedNUIntUnsignedRightShift = Lifted | NUInt | UnsignedRightShift, | ||
LiftedUserDefinedUnsignedRightShift = Lifted | UserDefined | UnsignedRightShift, |
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 didn't seem like this was tested, should it also be commented out with a prototype for now? #Resolved
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 didn't seem like this was tested, should it also be commented out with a prototype for now?
I do not think it is strictly necessary. Working on user-defined operators now (for the next PR)
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.
Alright. I don't have a problem with it, was just curious since you commented out the non-lifted variant.
@jcouv, @dotnet/roslyn-compiler For the second review |
3 similar comments
@jcouv, @dotnet/roslyn-compiler For the second review |
@jcouv, @dotnet/roslyn-compiler For the second review |
@jcouv, @dotnet/roslyn-compiler For the second review |
@@ -225,6 +225,10 @@ private void EmitBinaryOperatorInstruction(BoundBinaryOperator expression) | |||
} | |||
break; | |||
|
|||
case BinaryOperatorKind.UnsignedRightShift: |
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.
Consider adding an assertion in IsUnsignedBinaryOperator
that it's not meant to be used on an unsigned right shift. #Resolved
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.
Consider adding an assertion in
IsUnsignedBinaryOperator
that it's not meant to be used on an unsigned right shift.
Will add in one of the next PRs
case BinaryOperatorKind.IntUnsignedRightShift: | ||
return (int)(((uint)valueLeft.Int32Value) >> valueRight.Int32Value); // Switch to `valueLeft.Int32Value >>> valueRight.Int32Value` once >>> becomes available | ||
case BinaryOperatorKind.NIntUnsignedRightShift: | ||
return (valueLeft.Int32Value >= 0) ? valueLeft.Int32Value >> valueRight.Int32Value : null; |
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 didn't understand why we can't compute the constant result when valueLeft.Int32Value < 0
#Closed
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 didn't understand why we can't compute the constant result when
valueLeft.Int32Value < 0
Binary representation of negative values depends on the actual size of the type.
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.
Worked it out on paper. Makes sense
@@ -1951,12 +1951,21 @@ internal static SpecialType GetEnumPromotedType(SpecialType underlyingType) | |||
case BinaryOperatorKind.IntRightShift: | |||
case BinaryOperatorKind.NIntRightShift: | |||
return valueLeft.Int32Value >> valueRight.Int32Value; | |||
case BinaryOperatorKind.IntUnsignedRightShift: | |||
return (int)(((uint)valueLeft.Int32Value) >> valueRight.Int32Value); // Switch to `valueLeft.Int32Value >>> valueRight.Int32Value` once >>> becomes available |
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.
nit: Consider opening a tracking issue, otherwise we'll likely forget
@@ -414,6 +414,32 @@ void M(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int | |||
VerifyOperationTreeAndDiagnosticsForTest<InvocationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics); | |||
} | |||
|
|||
[CompilerTrait(CompilerFeature.IOperation)] | |||
[Fact] | |||
public void TestBinaryOperators_UnsignedRightShift() |
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.
Should we also have IOp tests with >>>=
, or will that be a later PR? #Resolved
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.
Should we also have IOp tests with
>>>=
, or will that be a later PR?
Yes we should have those. I will add them in a later PR.
[InlineData("decimal", "nuint")] | ||
[InlineData("decimal", "float")] | ||
[InlineData("decimal", "double")] | ||
[InlineData("decimal", "decimal")] |
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.
Consider using CombinatorialData
(more compact, less tedious to type/review). This applies to other tests as well #Resolved
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.
Consider using
CombinatorialData
(more compact, less tedious to type/review). This applies to other tests as well
Will simplify in one of the next PRs.
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.
Actually, I do not think CombinatorialData
is going to work. We are not testing cross product of two type sets.
} | ||
"; | ||
var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, | ||
parseOptions: TestOptions.RegularPreview); |
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.
nit: all these tests don't need TestOptions.RegularPreview
(that's the default) #WontFix
Assert.Equal("x >>> y", unsignedShift.ToString()); | ||
Assert.Equal("x >> y", shift.ToString()); | ||
|
||
var unsignedShiftSymbol = (IMethodSymbol)model.GetSymbolInfo(unsignedShift).Symbol; |
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.
Consider verifying GetTypeInfo
too, or adding to test plan #WontFix
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.
Consider verifying GetTypeInfo too, or adding to test plan
I do not find this particularly interesting. Completeness is the only reason to have them. I am not adding new bound nodes, there is nothing new there in terms of calculating type info. Symbol info is interesting because we are supposed to synthesize operator symbols for intrinsic operators.
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.
LGTM Thanks (iteration 1), but reducing the verbosity of the InlineData sequences in the tests would be really appreciated. Also a couple of nits to consider
https://github.com/dotnet/csharplang/blob/main/proposals/unsigned-right-shift-operator.md
Test plan #60433