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

Ensure that INumberBase implements IUtf8SpanFormattable #88840

Merged
merged 5 commits into from
Jul 14, 2023

Conversation

tannergooding
Copy link
Member

Since IUtf8SpanFormattable is a net new interface in .NET 8, then we need to ensure that INumberBase implements it in the same release we can't hit a diamond problem in the future.

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, 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.

@ghost
Copy link

ghost commented Jul 13, 2023

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Issue Details

Since IUtf8SpanFormattable is a net new interface in .NET 8, then we need to ensure that INumberBase implements it in the same release we can't hit a diamond problem in the future.

Author: tannergooding
Assignees: tannergooding
Labels:

area-System.Numerics, new-api-needs-documentation

Milestone: -

else
{
utf16DestinationArray = ArrayPool<char>.Shared.Rent(destinationMaxCharCount);
utf16Destination = utf16DestinationArray.AsSpan(0, destinationMaxCharCount);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: No slice is needed here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Its not "needed", but its nice to be consistent with the general pattern that is needed in most algorithms. It helps avoid copy/paste or refactoring errors.

It also helps limit the amount of work done if the utf8Buffer would've been "too small" and the rented buffer was much larger, for whatever reason (that is, it allows faster and more consistent failure).

…we couldn't transcode back to valid UTF-8 in the DIM
{
char[]? utf16DestinationArray;
scoped Span<char> utf16Destination;
int destinationMaxCharCount = Encoding.UTF8.GetMaxCharCount(utf8Destination.Length);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I would just use utf8Destination.Length directly for this. That is, just assume ASCII to simplify things. You're not going to be able to tell how many UTF-8 bytes the intermediate buffer will transcode to until after the intermediate buffer has already been populated, so...meh.

Copy link
Member Author

Choose a reason for hiding this comment

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

Same as above, its not strictly "needed" and in the 99% case won't even be different since it really only is length + 1 and check for overflow.

But, its nice to be consistent with the generally "correct" pattern and helps cover any edges that might creep in for user code. Our own APIs won't be hitting the DIM anyways.

{
if (utf16DestinationArray != null)
{
// Return rented buffers if necessary
Copy link
Member

Choose a reason for hiding this comment

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

nit, I don't think these comments add much

Copy link
Member Author

Choose a reason for hiding this comment

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

It’s a copy/paste of the same comment we have throughout similar code. I agree it probably doesn’t add much, but it’s consistent atm

@panxn
Copy link

panxn commented Jul 17, 2023

This change causes C3611 error in my c++/cli project, any idea?

error C3611: 'System::Numerics::INumberBase::System::IUtf8SpanFormattable.TryFormat': a sealed function cannot have a pure-specifier

I can simply reproduce it with following sample:

    // in C# project
    public interface Interface
    {
        bool TryFormat();
    }
    public interface Interface2 : Interface
    {
        bool Interface.TryFormat()
        {
            return true;
        }
    }
    public class MyClass : Interface2
    {
    }

    // in C++/CLI project, error C3611
    auto p = gcnew CSharpDll::MyClass();

@tannergooding
Copy link
Member Author

This change causes C3611 error in my c++/cli project, any idea?

Seems like a C++/CLI bug that is exposed when overriding an instance DIM in a derived interface.

This doesn't occur if the DIM is done on the interface that defines the API (that is, this wouldn't be an issue if the DIM was done on IUtf8SpanFormattable itself, but that would require it to implement ISpanFormattable).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants