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

Extend IL/ILAsm/ILDasm to represent attributes on type constraints #13005

Closed
jcouv opened this issue Jun 28, 2019 · 6 comments
Closed

Extend IL/ILAsm/ILDasm to represent attributes on type constraints #13005

jcouv opened this issue Jun 28, 2019 · 6 comments
Assignees
Milestone

Comments

@jcouv
Copy link
Member

jcouv commented Jun 28, 2019

We have not yet discussed a specific proposal for how to represent this in IL. Tagging @RussKeldorph.

Relates to dotnet/roslyn#29997

@jbevain
Copy link
Contributor

jbevain commented Jun 28, 2019

That's going to be a bit annoying as the constraints are currently inlined in the generic parameter declaration. What about introducing a new .constraint keyword for scenarios where you want a custom attribute or do no want to add the constraint inline in the brackets?

.class private auto ansi Library`1<T>
{
    .param type T
    .constraint class Foo.IInterface
    .custom instance void class System.Runtime.CompilerServices.NullableAttribute::'.ctor'(unsigned int8)
}

.constraint could be limited to class and valuetype arguments.

@dseefeld
Copy link
Contributor

This is impacting source-build. We rely on round-tripping some assemblies using ildasm/ilasm to eliminate prebuilts. Not having the ability to round-trip these assemblies with nullable attributes will increasingly impact our ability to get to zero prebuilts, especially as usage of the nullable attribute increases.

@briansull
Copy link
Contributor

Ok I have implemented the following ildasm:

#nullable enable
public class C2 { }
public interface I2<T> { }

public class C<T> where  T : C2?, I2<(int a, int b)> 
{ 
    void M<U>(C2? x) where U : C2? { }
}

Produces this IL:

.class public auto ansi beforefieldinit C`1<(C2, class I2`1<valuetype System.ValueTuple`2<int32,int32>>) T>
       extends [mscorlib]System.Object
{
  .param constraint   T, C2
    .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) 
  .param constraint   T, class I2`1<valuetype System.ValueTuple`2<int32,int32>>
    .custom instance void [mscorlib]System.Runtime.CompilerServices.TupleElementNamesAttribute::.ctor(string[]) = ( 01 00 02 00 00 00 01 61 01 62 00 00 )             // .......a.b..
    .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 00 00 00 ) 
  .method private hidebysig instance void 
          M(class C2 x) cil managed
  {
    .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) 
    // Code size       2 (0x2)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ret
  } // end of method C`1::M

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       8 (0x8)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  nop
    IL_0007:  ret
  } // end of method C`1::.ctor

} // end of class C`1

dgrunwald referenced this issue in icsharpcode/ILSpy Aug 11, 2019
@BruceForstall
Copy link
Member

I don't believe this meets the bar for 3.0, so moving Milestone to 5.0.

@briansull
Copy link
Contributor

briansull commented Aug 27, 2019

Example syntax:

#nullable enable
public class C2 { }
public interface I2<T> { }

public class C<T> where  T : C2?, I2<(int a, int b)> 
{ 
    void M<U>(C2? x) where U : C2? { }
}

.class public auto ansi beforefieldinit C`1<(C2, class I2`1<valuetype System.ValueTuple`2<int32,int32>>) T>
       extends [mscorlib]System.Object
{
  .param constraint   T, C2
    .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) 
  .param constraint   T, class I2`1<valuetype System.ValueTuple`2<int32,int32>>
    .custom instance void [mscorlib]System.Runtime.CompilerServices.TupleElementNamesAttribute::.ctor(string[]) = ( 01 00 02 00 00 00 01 61 01 62 00 00 )             // .......a.b..
    .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 01 00 00 00 ) 
  .method private hidebysig instance void 
          M(class C2 x) cil managed
  {

@briansull
Copy link
Contributor

Fixed with:

Implement ilasm and ildasm support for .param constraint with Custom attributes dotnet/coreclr#26219

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants