dotnet / dotnet/linker

Readonly Type fields should be treated like Type variables

Open
#1,664 3 comments 0 reactions 0 assignees View on GitHub
area-Linker: DataFlow proposal
Dominant language
C#
Stars
392
Forks
128
Avg merge
2d 10h
Merged PRs (30d)
2

Description

In trying to make the following code trim compatible:

https://github.com/dotnet/runtime/blob/1a1ad943288b512a877222e2fdede0bc198df333/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/GenerateHelper.cs#L81-L103

I wanted to write the following code:

```C#
internal class XmlILStorageMethods
{
public readonly Type SeqType;
public readonly MethodInfo SeqAdd;

public XmlILStorageMethods(Type storageType)
{
if (storageType == typeof(XPathNavigator))
{
SeqType = typeof(XmlQueryNodeSequence);
SeqAdd = SeqType.GetMethod("AddClone")!;
}
else if (storageType == typeof(XPathItem))
{
SeqType= typeof(XmlQueryItemSequence);
SeqAdd = SeqType.GetMethod("AddClone")!;
}
else
{
SeqType = typeof(XmlQuerySequence<>).MakeGenericType(storageType);
SeqAdd = SeqType.GetMethod("Add")!;
}

FieldInfo? seqEmpty = SeqType.GetField("Empty");
}
}
```

However, the linker warns here that I haven't annotated the `Type SeqType` field appropriately on the calls to `.GetMethod` and that final line `SeqType.GetField("Empty");`. But in this case, the field is readonly, and it is unconditionally set above the usage.

```
F:\git\runtime\src\libraries\System.Private.Xml\src\System\Xml\Xsl\IlGen\GenerateHelper.cs(99,17): Trim analysis warning IL2080: System.Xml.Xsl.IlGen.XmlILStorageMethods.XmlILStorageMethods(Type): The requirements declared via the 'DynamicallyAccessedMembersAttribute' on the field 'System.Type System.Xml.Xsl.IlGen.XmlILStorageMethods::SeqType' don't match those on the implicit 'this' parameter of method 'System.Type.GetMethod(String)'. The source value must declare at least the same requirements as those declared on the target location it's assigned to [F:\git\runtime\src\libraries\src.proj]
F:\git\runtime\src\libraries\System.Private.Xml\src\System\Xml\Xsl\IlGen\GenerateHelper.cs(116,13): Trim analysis warning IL2080: System.Xml.Xsl.IlGen.XmlILStorageMethods.XmlILStorageMethods(Type): The requirements declared via the 'DynamicallyAccessedMembersAttribute' on the field 'System.Type System.Xml.Xsl.IlGen.XmlILStorageMethods::SeqType' don't match those on the implicit 'this' parameter of method 'System.Type.GetMethod(String,Type[])'. The source value must declare at least the same requirements as those declared on the target location it's assigned to [F:\git\runtime\src\libraries\src.proj]
F:\git\runtime\src\libraries\System.Private.Xml\src\System\Xml\Xsl\IlGen\GenerateHelper.cs(115,13): Trim analysis warning IL2080: System.Xml.Xsl.IlGen.XmlILStorageMethods.XmlILStorageMethods(Type): The requirements declared via the 'DynamicallyAccessedMembersAttribute' on the field 'System.Type System.Xml.Xsl.IlGen.XmlILStorageMethods::SeqType' don't match those on the implicit 'this' parameter of method 'System.Type.GetMethod(String,Type[])'. The source value must declare at least the same requirements as those declared on the target location it's assigned to [F:\git\runtime\src\libraries\src.proj]
F:\git\runtime\src\libraries\System.Private.Xml\src\System\Xml\Xsl\IlGen\GenerateHelper.cs(104,17): Trim analysis warning IL2080: System.Xml.Xsl.IlGen.XmlILStorageMethods.XmlILStorageMethods(Type): The requirements declared via the 'DynamicallyAccessedMembersAttribute' on the field 'System.Type System.Xml.Xsl.IlGen.XmlILStorageMethods::SeqType' don't match those on the implicit 'this' parameter of method 'System.Type.GetMethod(String)'. The source value must declare at least the same requirements as those declared on the target location it's assigned to [F:\git\runtime\src\libraries\src.proj]
F:\git\runtime\src\libraries\System.Private.Xml\src\System\Xml\Xsl\IlGen\GenerateHelper.cs(109,17): Trim analysis warning IL2080: System.Xml.Xsl.IlGen.XmlILStorageMethods.XmlILStorageMethods(Type): The requirements declared via the 'DynamicallyAccessedMembersAttribute' on the field 'System.Type System.Xml.Xsl.IlGen.XmlILStorageMethods::SeqType' don't match those on the implicit 'this' parameter of method 'System.Type.GetMethod(String)'. The source value must declare at least the same requirements as those declared on the target location it's assigned to [F:\git\runtime\src\libraries\src.proj]
F:\git\runtime\src\libraries\System.Private.Xml\src\System\Xml\Xsl\IlGen\GenerateHelper.cs(112,13): Trim analysis warning IL2080: System.Xml.Xsl.IlGen.XmlILStorageMethods.XmlILStorageMethods(Type): The requirements declared via the 'DynamicallyAccessedMembersAttribute' on the field 'System.Type System.Xml.Xsl.IlGen.XmlILStorageMethods::SeqType' don't match those on the implicit 'this' parameter of method 'System.Type.GetField(String)'. The source value must declare at least the same requirements as those declared on the target location it's assigned to [F:\git\runtime\src\libraries\src.proj]
F:\git\runtime\src\libraries\System.Private.Xml\src\System\Xml\Xsl\IlGen\GenerateHelper.cs(117,13): Trim analysis warning IL2080: System.Xml.Xsl.IlGen.XmlILStorageMethods.XmlILStorageMethods(Type): The requirements declared via the 'DynamicallyAccessedMembersAttribute' on the field 'System.Type System.Xml.Xsl.IlGen.XmlILStorageMethods::SeqType' don't match those on the implicit 'this' parameter of method 'System.Type.GetMethod(String)'. The source value must declare at least the same requirements as those declared on the target location it's assigned to [F:\git\runtime\src\libraries\src.proj]
```

To work around the linker, I am forced to introduce an intermediate variable for `Type sequenceType`, and use that to call `.GetMethod` and `.GetField("Empty")`. Then set the field to the variable at the end.

In this case, since the field is `readonly` and it is unconditionally set to a concrete Type above, I shouldn't need to be forced to inject a local variable just to make the linker happy.

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.