Skip to content

Removing the struct/unmanaged constraint from the Vector types #87283

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

Merged
merged 1 commit into from
Jun 9, 2023

Conversation

tannergooding
Copy link
Member

@tannergooding tannergooding commented Jun 8, 2023

This resolves #85893

This does not actually utilize the relaxed constraint anywhere yet. Give the churn involved in removing the constraints, I opted to leave that to a future PR.

@ghost
Copy link

ghost commented Jun 8, 2023

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 ghost assigned tannergooding Jun 8, 2023
@tannergooding tannergooding requested a review from stephentoub June 8, 2023 16:39
@ghost
Copy link

ghost commented Jun 8, 2023

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

Issue Details

This resolves #85893

Author: tannergooding
Assignees: -
Labels:

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

Milestone: -

public static Vector<T> LoadAlignedNonTemporal<T>(T* source)
where T : unmanaged => LoadAligned(source);
public static Vector<T> LoadAlignedNonTemporal<T>(T* source) => LoadAligned(source);
#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T')
Copy link
Member

Choose a reason for hiding this comment

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

This is unrelated, yes? It's fine, just confirming.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, nevermind, it is related, it was relying on unmanaged being a subset of struct.

Copy link
Member Author

Choose a reason for hiding this comment

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

Which part in particular?

The change here is part of the general removal of the struct constraint so the code can be generally used in less constrained contexts.

This was originally where T : unmanaged because at the time C# didn't allow T* for unconstrained T. Now C# allows it, but surfaces a warning that T could be "managed".

If we didn't relax this, then Load wouldn't be callable from an unconstrained context and if we didn't suppress the warning then compilation would fail. Callers will get their own version of the warning if they are likewise not constrained to where T : unmanaged.

{
T sum = default;
T sum = default!;
Copy link
Member

Choose a reason for hiding this comment

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

This makes me realize this change could actually introduce new warnings in 3rd party code. That's fine, just something to keep in mind. I'd been thinking of the removal of the constraint as being completely non-breaking.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think that's the case....

This warning is because we made an explicit change to the constraint such that its now unconstrained and now could be string, therefore default would be invalid for the specified T.

Existing callers must be where T : struct, so the compiler would consider T to be always non-nullable and the result to likewise be always non-nullable.

Copy link
Member

@stephentoub stephentoub Jun 8, 2023

Choose a reason for hiding this comment

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

Existing callers must be where T : struct

Ah, of course. I was thinking someone could have defined a helper function operating on VectorXx<T>, and inside that used default(T) without !, but as you say, they would have had to constrain T. So they'd have to change their code in some way for this to start triggering.

@tannergooding
Copy link
Member Author

System.Private.Corelib is actually a bit smaller with this change, which is nice.

Before: 11,848 KB
After:  11,732 KB

CC. @vargaz, @SamMonoRT -- Are there any checks we need to do for the Mono side? The particular consideration is around whether the lack of constraint will negatively impact Mono AOT due to the existence of USG. Since its now unconstrained it "could" be say string on the user end. The actual code for that will always throw, but it could warrant special-casing this to avoid new kinds of generic code explosion or similar.

@SamMonoRT
Copy link
Member

cc @lambdageek

@vargaz
Copy link
Contributor

vargaz commented Jun 8, 2023

I don't think this will affect mono.

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.

[API Proposal]: Remove struct constraint from Vector*<T>
4 participants