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

Design to support ByRefLike types in Generics #67129

Merged
merged 14 commits into from
Nov 4, 2022

Conversation

AaronRobinsonMSFT
Copy link
Member

@AaronRobinsonMSFT AaronRobinsonMSFT commented Mar 25, 2022

Adding in a proposal to support ByRefLike type in Generics. This work is supported by #63768 and contributes toward #65112.

/cc @jkotas @davidwrighton @jaredpar @cston @RikkiGibson @AlekseyTs

docs/design/features/byreflike-generics.md Outdated Show resolved Hide resolved
docs/design/features/byreflike-generics.md Outdated Show resolved Hide resolved
docs/design/features/byreflike-generics.md Outdated Show resolved Hide resolved
docs/design/features/byreflike-generics.md Show resolved Hide resolved
@danmoseley
Copy link
Member

Cc @steveharter

@AaronRobinsonMSFT
Copy link
Member Author

@lambdageek for mono and @tgani-msft for C++/CLI FYI.

docs/design/features/byreflike-generics.md Outdated Show resolved Hide resolved
docs/design/features/byreflike-generics.md Outdated Show resolved Hide resolved
docs/design/features/byreflike-generics.md Outdated Show resolved Hide resolved
@AaronRobinsonMSFT
Copy link
Member Author

Any other feedback on this design?

Copy link
Contributor

@tgani-msft tgani-msft left a comment

Choose a reason for hiding this comment

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

Are these types importable via the COM metadata APIs? The C++ compiler uses only these.

@AaronRobinsonMSFT
Copy link
Member Author

AaronRobinsonMSFT commented Apr 15, 2022

@tgani-msft As in, can they be acquired through the IMetaDataImport interface? Yes. A new enum value is being added though. That will need to be updated. Can you share an example of how the compiler uses IMetaDataImport so we can record the pattern?

@tgani-msft
Copy link
Contributor

@tgani-msft As in, can they be acquired through the IMetaDataImport interface? Yes. A new enum value is being added though. That will need to be updated. Can you share an example of how the compiler uses IMetaDataImport so we can record the pattern?

I'll send you a link to the source code directly, via email.

@RikkiGibson
Copy link
Contributor

I think this came up elsewhere (maybe from @teo-tsirpanis), but is there any need to take special effort to make types "conditionally by-ref-like" depending on their type arguments? For example, imagine if we wanted to let people use nullable ref structs. It would be good to allow things like boxing, heap escape, etc. depending on the type arguments.

ref struct RS
{
    public ref int X;
}

namespace System
{
    // somehow we denote here that this is "only a ref struct if T is a ref struct".
    public struct Nullable<T> where T : struct allow T : ref struct // or whatever syntax we use
    {
        T value;
        // ...
    }
}

void M(RS? maybeRs, ref int X)
{
    if (maybeRs != null)
    {
        maybeRs.Value.X = ref X;
    }
    object obj = maybeRs; // error
}

void M2(int? maybeInt)
{
    object obj = maybeInt; // ok
}

It's possible the answer here is no, don't bother doing this, or punt it to something further down the line, but seems worth considering as part of this whole area.

@AaronRobinsonMSFT
Copy link
Member Author

but is there any need to take special effort to make types "conditionally by-ref-like" depending on their type arguments?

That seems like a much broader feature given T would now influence the use of the Generic type. For example, if this were to be implemented we would also need to update the semantics of IsByRefLikeAttribute or create another mechanism that is predicated on other features. At present, I don't see anything here that would limit this, but do have some concerns about this feature and the complexity it would introduce in the type system and runtime in general.

@AaronRobinsonMSFT
Copy link
Member Author

The only prior art I can think of for this sort of thing is in Interop when a T influences the blittability of a type.

@RikkiGibson
Copy link
Contributor

RikkiGibson commented Apr 22, 2022

FWIW, there are a few existing places in the compiler where the types of fields after substitution affect usage of a struct. For example: SharpLab. (it sounds like this might be very similar/related to blittability.)

struct S<T>
{
    public T field;
}

class Program
{
    unsafe void M1(S<int>* ptr) { } // ok
    unsafe void M2(S<object>* ptr) { } // error
}

@AaronRobinsonMSFT
Copy link
Member Author

FWIW, there are a few existing places in the compiler where the types of fields after substitution affect usage of a struct. For example: SharpLab. (it sounds like this might be very similar/related to blittability.)

Agreed, but not metadata. For example, the following might be unintuitive from a reflection standpoint:

struct S<T> allow T : ref struct
            ref struct when T : ref struct
{ }

Console.WriteLine(typeof(S<>).IsByRefLike); // False
Console.WriteLine(typeof(S<int>).IsByRefLike); // False
Console.WriteLine(typeof(S<Span<int>>).IsByRefLike);  // True

@hez2010
Copy link
Contributor

hez2010 commented May 10, 2022

How about enabling overload by generic constraints so we can have both Foo<T> where T : struct and Foo<T> where T : ref struct?

@AaronRobinsonMSFT AaronRobinsonMSFT modified the milestones: 7.0.0, 8.0.0 Jul 1, 2022
@stephentoub
Copy link
Member

@AaronRobinsonMSFT, can this be merged? Presumably we're fine updating the design doc as the design evolves and we don't need to block the PR on having 100% of the answers set in stone?

@AaronRobinsonMSFT
Copy link
Member Author

@AaronRobinsonMSFT, can this be merged?

I think so. It is accurate regarding the current state of support in the runtime.

Presumably we're fine updating the design doc as the design evolves and we don't need to block the PR on having 100% of the answers set in stone?

Agreed.

@stephentoub stephentoub merged commit 87d51b2 into dotnet:main Nov 4, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2022
@AaronRobinsonMSFT AaronRobinsonMSFT deleted the generic_byreflike_design branch January 16, 2024 18:40
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.