Skip to content

Champion: Unmanaged constructed types (16.3, Core 3) #1744

Open

Description

Summary

Provide a way to take the address of a generic struct provided it does not contain any "managed" (GC-tracked) types.

For example, the following generic type is "unmanaged":

public struct MyStruct<T> where T : unmanaged
{
    public T field;
}

Motivation

Today, users have the ability to declare structs and take the address of it (in an unsafe context) provided that it is not considered a "managed" type.

  • The compiler currently reports generic structs as "managed" types, even though they are not GC-tracked

However, there is nothing in the runtime preventing a user from taking the address of a generic struct and, in certain scenarios, it may be desirable to allow this.

One such example is the System.Runtime.Intrinsics.Vector128<T> type, which contains no GC tracked objects. The type is designed to be used in high-performance and generally unsafe scenarios, but there are certain operations (such as stackalloc, pinning, etc) which cannot be done in C# today.

Design

The C# 6 spec states that an unmanaged_type is:

isn't a reference_type or constructed type, and doesn't contain reference_type or constructed type fields at any level of nesting. In other words, an unmanaged_type is one of the following:

  • sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
  • Any enum_type.
  • Any pointer_type.
  • Any user-defined struct_type that is not a constructed type and contains fields of unmanaged_types only.

This change would remove the restriction that unmanaged_type cannot be a constructed type. Instead, constructed types would be unmanaged if they meet the requirements of general user-defined struct types.

Drawbacks

The compiler may need to do additional validation in order to validate that a user-defined generic struct is "ok" to use.

Notes

The user will still not be able to take the address of any type, which is possible to do in IL code today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Labels

Implemented Needs ECMA SpecThis feature has been implemented in C#, but still needs to be merged into the ECMA specificationProposal champion

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions