-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Ensure the generic math interfaces are implemented implicitly where possible #66748
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs
Outdated
Show resolved
Hide resolved
/// <inheritdoc cref="IAdditiveIdentity{TSelf, TResult}.AdditiveIdentity" /> | ||
static char IAdditiveIdentity<char, char>.AdditiveIdentity => (char)0; |
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.
API review will need to discuss if exposing AdditiveIdentity
, MultiplicativeIdentity
, One
, and Zero
make sense for char
. They are not exposed until that discussion happens.
All of the operators exist in regular C#, but unlike the other types the members being exposed publicly may be potentially confusing or "incorrect" terminology for char
.
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
static char INumber<char>.Create<TOther>(TOther value) | ||
public static char Create<TOther>(TOther value) |
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.
The Create
APIs are still pending being extracted to IConvertible
interfaces as per API review (dotnet/designs#205 (comment))
This will occur in a follow up PR. This PR is just making the incremental steps of taking the preview surface and exposing it publicly for simplicity
public const decimal MultiplicativeIdentity = 1m; | ||
|
||
/// <inheritdoc cref="ISignedNumber{TSelf}.NegativeOne" /> | ||
public const decimal NegativeOne = -1m; |
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.
Decimal already defines and exposes MinusOne
. This will need to be discussed in API review.
My own preference is MinusOne
is the "incorrect" name and we shouldn't propagate it to the other types or interfaces.
static decimal INumber<decimal>.Sign(decimal value) | ||
=> Math.Sign(value); | ||
/// <inheritdoc cref="INumber{TSelf}.Sign(TSelf)" /> | ||
static decimal INumber<decimal>.Sign(decimal value) => Math.Sign(value); |
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.
decimal
already exposes int Sign(decimal)
. We'll want to discuss in API review whether or not normalizing Sign(T)
as being special and always returning int
is desirable and how to reconcile the exposed API surface otherwise.
static byte System.IMultiplicativeIdentity<System.Byte,System.Byte>.MultiplicativeIdentity { get { throw null; } } | ||
static byte System.INumber<System.Byte>.One { get { throw null; } } | ||
static byte System.INumber<System.Byte>.Zero { get { throw null; } } | ||
public static System.Byte Abs(System.Byte value) { throw 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.
Just noting that GenerateReferenceSource
isn't consistent in when it picks System.Byte
vs byte
. It should likely prefer the latter since that's the default we use in source and is unambiguous.
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.
Likewise noting that GenerateReferenceSource
doesn't like static abstracts in interfaces
today. It doesn't include the relevant accessibility
modifier (such as public
) and it treats operators as their IL name, rather than their C# syntax (e.g. op_Addition
rather than operator +
).
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.
Thanks for commenting on these. Please accumulate all of the GenerateReferenceSource
issues you're encountering and log an issue in dotnet/arcade.
(some existing issues for reference)
@@ -3588,6 +3302,13 @@ public sealed partial class InsufficientMemoryException : System.OutOfMemoryExce | |||
public static System.IntPtr MaxValue { get { throw null; } } | |||
public static System.IntPtr MinValue { get { throw null; } } | |||
public static int Size { get { throw null; } } | |||
static nint System.IAdditiveIdentity<nint,nint>.AdditiveIdentity { get { throw 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.
Noting that GenerateReferenceSource
is not nint
vs IntPtr
aware and will not pick the appropriate of the type vs the keyword based on what's in source.
It happens to error in most of the right places if they don't line up due to the difference in attributes, however. It would just be nice if the task generated the right source from the start.
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsNotably this deviates from API review slightly. In API review, it was determined that interfaces should be implicitly implemented. However, most types cannot implement the operators implicitly. This comes down to causing issues with The meeting around IntPtr/UIntPtr is going to happen before the next API review and the deviation here is going to be raised in the next API review. It shouldn't be considered a blocker, however.
|
CC. @jeffhandley |
penultimate? What comes after that design decision? |
The upcoming meeting will make the decision on whether IntPtr/UIntPtr has the interface members implicitly or explicitly implemented or if some other modification will exist here. It will decide whether |
Right, I'm confused by the penultimate (i.e. next to last) part. There's another IntPtr/UIntPtr decision after that? |
The decision reached by the C# team and the relevant API review members present will need to be reiterated as part of the API review that occurs after (currently scheduled the next Tuesday after). It likely won't influence IntPtr/UIntPtr any further than that, but may influence our decisions around other APIs and how they're exposed. |
Ok, got it, good. I was worried there was some big lurking thing beyond I wasn't aware of :) |
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 skimmed the changes. Other than fixing the ODBC build and fixing the comments on the consts, LGTM.
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 reviewed all of the changes at ~65% thoroughness. It seems pretty mechanical, @tannergooding. Other than the places where you left comments, the APIs that are still blocked by language features, and the <inheritdoc>
feedback, is there anything else you'd like particular attention on?
// static checked byte IAdditionOperators<byte, byte, byte>.operator +(byte left, byte right) | ||
// => checked((byte)(left + right)); | ||
// /// <inheritdoc cref="IAdditionOperators{TSelf, TOther, TResult}.op_CheckedAddition(TSelf, TOther)" /> | ||
// static byte IAdditionOperators<byte, byte, byte>.operator checked +(byte left, byte right) => checked((byte)(left + right)); |
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.
Note to other reviewers:
The checked
operators are blocked by [Proposal]: Checked Operators · Issue #4665 · dotnet/csharplang
// /// <inheritdoc cref="IFloatingPoint{TSelf}.Exp10(TSelf)" /> | ||
// public static double Exp10(double x) => Math.Exp10(x); |
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.
Please remind me while all of these are still commented out? What are these APIs blocked on?
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.
These are APIs that are approved but not implemented on System.Math or System.MathF
Ideally we get them also implemented and exposed for .NET 7, but the "worst case" is they become DIMs in .NET vNext
// static sbyte IShiftOperators<sbyte, sbyte>.operator >>>(sbyte value, int shiftAmount) | ||
// => (sbyte)((byte)value >> shiftAmount); | ||
// /// <inheritdoc cref="IShiftOperators{TSelf, TResult}.op_UnsignedRightShift(TSelf, int)" /> | ||
// static sbyte IShiftOperators<sbyte, sbyte>.operator >>>(sbyte value, int shiftAmount) => (sbyte)((byte)value >> shiftAmount); |
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.
Note for other reviewers:
This is blocked by [Proposal]: Unsigned right shift operator · Issue #4682 · dotnet/csharplang
Thanks for looping me in on this. I skimmed the changes, as well as the reviewer comments. I agree with @jeffhandley that this seems mostly mechanical. LGTM at a high level. |
…ossible (dotnet#66748) * Updating generic math interfaces to be implicitly implemented where possible * Resolve a build error in OdbcConnection caused by new Parse APIs * Revert "Resolve a build error in OdbcConnection caused by new Parse APIs" This reverts commit 6fd7ec7. * Suppress CA1846 for System.Data.Odbc * Updating the xml doc comments for exposed constants
Notably this deviates from API review slightly. In API review, it was determined that interfaces should be implicitly implemented. However, most types cannot implement the operators implicitly. This comes down to causing issues with
System.Linq.Expressions
for a couple types and it being a technically problematic scenario from the perspective of the C# Language Spec (but not the current Roslyn implementation). Likewise,IntPtr
andUIntPtr
have a pending design discussion with relevant folks from the C# Language Design Team to determine what the penultimate behavior is going to be.The meeting around IntPtr/UIntPtr is going to happen before the next API review and the deviation here is going to be raised in the next API review. It shouldn't be considered a blocker, however.