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

Proposal: Unmanaged constructed types #1504

Closed
RossNordby opened this issue May 8, 2018 · 10 comments
Closed

Proposal: Unmanaged constructed types #1504

RossNordby opened this issue May 8, 2018 · 10 comments

Comments

@RossNordby
Copy link

While the unmanaged generic constraint (#187) helps clean up a bunch of code where generics and pointers interact, constructed types still complicate things. For example:

        struct Toot<T> where T : unmanaged
        {
        }

        void Poot<T>(T t) where T : unmanaged
        {
        }

        void Shoot()
        {
            var toot = new Toot<int>();
            var patoot = &toot;
            Poot(toot);
        }

Toot<T> cannot be classified as an unmanaged type due to the generic type parameter, so attempts to take a pointer or pass it as an unmanaged generic parameter fail.

This can force more complex use cases into awkward workarounds, usually involving Unsafe to accomplish something similar in an uglier way. It can also be a pretty surprising restriction- notably, not even the CS8377 error mentions the constructed type limitation:

The type 'Toot<int>' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'Poot<T>(T)'

Lifting this restriction would reduce the need for ugly workarounds. (And it could marginally improve codegen in cases that currently rely on jumping through multiple Unsafe hoops that the JIT doesn't fully collapse.)

@hypeartist
Copy link

Any news on this one?
This issue really limits hard the usefulness of unmanaged constraint.

@sgf
Copy link

sgf commented Jun 27, 2018

where T is int,uint..
where T not is int,uint..

if can be this will better

im often need define a function
like:

Method<T>(T input) where T is ... //... is some types

@dzmitry-lahoda
Copy link

I did some research here expanding from pointers to pointer-less code examples https://stackoverflow.com/questions/52228109/a-generic-construct-requires-that-the-type-cellt-is-an-unmanaged-type

@xoofx
Copy link
Member

xoofx commented Oct 17, 2018

How can we proceed on this? Can I send a PR to reformulate this line about unmanaged_type:

from:

Any user-defined struct_type that is not a constructed type and contains fields of unmanaged_types only.

to:

Any user-defined struct_type that contains fields of unmanaged_types only.

It has been claimed that this would require a CLR change, but the CLR team seems to indicate the contrary and in my experience, I have been using this even before unmanaged constraint exist in the specs, with a few IL rewrite indirection. So I don't see why we should exclude constructed type

cc: @MadsTorgersen

@tannergooding
Copy link
Member

This is related to #1744

@xoofx
Copy link
Member

xoofx commented Oct 17, 2018

@tannergooding yep, apart from a one-line change in the spec, what do we need to proceed with your proposal? Someone to champion it or we need to ask for a LDM? I haven't looked at Roslyn but I hope the changes there to be hopefully minimal (there is already a check for unmanaged types) and I don't expect any changes to the CLR.

@tannergooding
Copy link
Member

It requires someone from LDM to champion it, take it to LDM, and for it to get approved. Then it requires someone to implement it.

@xoofx
Copy link
Member

xoofx commented Oct 17, 2018

It requires someone from LDM to champion it, take it to LDM, and for it to get approved. Then it requires someone to implement it.

Ok good, so who could we ping to champion it and take it to LDM then? 😉

@tannergooding
Copy link
Member

@xoofx, it has now been championed: #1937

@YairHalberstadt
Copy link
Contributor

Closing as championed in #1937 and implemented in C# 8

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

No branches or pull requests

7 participants