-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Add missing generic constraints #101504
Add missing generic constraints #101504
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,7 +65,7 @@ public ByteEqualityComparer() { } | |
public override int GetHashCode() { throw null; } | ||
public override int GetHashCode(byte b) { throw null; } | ||
} | ||
public sealed partial class EnumEqualityComparer<T> : System.Collections.Generic.EqualityComparer<T>, System.Runtime.Serialization.ISerializable where T : struct | ||
public sealed partial class EnumEqualityComparer<T> : System.Collections.Generic.EqualityComparer<T>, System.Runtime.Serialization.ISerializable where T : struct, System.Enum | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not exposed publicly in reference assembly. |
||
{ | ||
public EnumEqualityComparer() { } | ||
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -362,17 +362,17 @@ public void FinalRelease() { } | |
System.Runtime.InteropServices.Marshalling.VirtualMethodTableInfo System.Runtime.InteropServices.Marshalling.IUnmanagedVirtualMethodTableProvider.GetVirtualMethodTableInfoForKey(System.Type type) { throw null; } | ||
} | ||
[System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.Exception), System.Runtime.InteropServices.Marshalling.MarshalMode.UnmanagedToManagedOut, typeof(System.Runtime.InteropServices.Marshalling.ExceptionAsDefaultMarshaller<>))] | ||
public static partial class ExceptionAsDefaultMarshaller<T> where T : struct | ||
public static partial class ExceptionAsDefaultMarshaller<T> where T : unmanaged | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW this would not have produced a runtime exception. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jkoritzinsky let me know that for these we want the constraints here.
|
||
{ | ||
public static T ConvertToUnmanaged(System.Exception e) { throw null; } | ||
} | ||
[System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.Exception), System.Runtime.InteropServices.Marshalling.MarshalMode.UnmanagedToManagedOut, typeof(System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller<>))] | ||
public static partial class ExceptionAsHResultMarshaller<T> where T : struct | ||
public static partial class ExceptionAsHResultMarshaller<T> where T : unmanaged, System.Numerics.INumber<T> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently fails at runtime with
|
||
{ | ||
public static T ConvertToUnmanaged(System.Exception e) { throw null; } | ||
} | ||
[System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute(typeof(System.Exception), System.Runtime.InteropServices.Marshalling.MarshalMode.UnmanagedToManagedOut, typeof(System.Runtime.InteropServices.Marshalling.ExceptionAsNaNMarshaller<>))] | ||
public static partial class ExceptionAsNaNMarshaller<T> where T : struct | ||
public static partial class ExceptionAsNaNMarshaller<T> where T : unmanaged, System.Numerics.IFloatingPointIeee754<T> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently fails at runtime with:
|
||
{ | ||
public static T ConvertToUnmanaged(System.Exception e) { throw null; } | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2492,7 +2492,7 @@ protected Enum() { } | |
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("EnumFormat")] string? format) { throw null; } | ||
[System.ObsoleteAttribute("The provider argument is not used. Use ToString(String) instead.")] | ||
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("EnumFormat")] string? format, System.IFormatProvider? provider) { throw null; } | ||
public static bool TryFormat<TEnum>(TEnum value, System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("EnumFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>)) where TEnum : struct { throw null; } | ||
public static bool TryFormat<TEnum>(TEnum value, System.Span<char> destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("EnumFormat")] System.ReadOnlySpan<char> format = default(System.ReadOnlySpan<char>)) where TEnum : struct, System.Enum { throw null; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be removed in the implementation instead. Notice that TryParse APIs on this type do not have the Enum constraint. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stephentoub what do you think? You added the API with the constraint in 62f3eb2 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As with above this already fails at runtime already with:
The unconstrained generic methods (like Parse and TryParse) fail with:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We approved it with the constraint but I believe this was because it was proposed like that and it made sense to us. Not having the constraint seems fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I'll remove the constraints from both ref and source and ensure that this API checks the T and throws an argument exception then (unless @stephentoub mentions otherwise). |
||
public static bool TryParse(System.Type enumType, System.ReadOnlySpan<char> value, bool ignoreCase, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out object? result) { throw null; } | ||
public static bool TryParse(System.Type enumType, System.ReadOnlySpan<char> value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out object? result) { throw null; } | ||
public static bool TryParse(System.Type enumType, string? value, bool ignoreCase, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out object? result) { 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.
Are all of these internal/non-public types?
Adding a constraint is a binary breaking, so just wanting to double check. -- notably, changing
struct
tounmanaged
is binary compatible, but may not be source compatibleThere 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 looks to me like they're all impacting the ref assembly, so users calling these methods from unconstrained or less constrained APIs will break on roll forward.
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 all public types. I've marked this change breaking. The constraints were already present in the runtime so I believe folks would have already observed runtime errors if they were violating the constraint.
If we don't want to add the source breaking for any of these we should remove the runtime constraint.
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 was definitely more concerned about binary breaks, I think source breaks are fine particularly given that a TypeLoadException was already occurring.