dotnet / dotnet/csharplang

Champion: Unmanaged constructed types (16.3, Core 3)

Open
#1,744 14 comments 60 reactions 2 assignees Claimed by @jaredpar View on GitHub
Implemented Needs ECMA Spec Proposal champion
Dominant language
C#
Stars
12.7k
Forks
1.1k
Avg merge
11h 1m
Merged PRs (30d)
3

Description

## Summary
[summary]: #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":
```C#
public struct MyStruct where T : unmanaged
{
public T field;
}
```

## Motivation
[motivation]: #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` 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
[design]: #design

The [C# 6 spec](https://github.com/dotnet/csharplang/blob/master/spec/unsafe-code.md#pointer-types) 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
[drawbacks]: #drawbacks

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

## Notes
[notes]: #notes

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

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.