ILLinker will sometimes not detect the usage of a generic method and substitute the contents
- Dominant language
- C#
- Stars
- 392
- Forks
- 128
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 2
Description
This was detected while trying to annotate a method in the dotnet/runtime repo which depends on a generic method from a generic class. The class in question is:
```c#
[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/System.Collections.Generic")]
internal sealed class KeyValuePairAdapter : IKeyValuePairAdapter
{
// .... other members
internal KeyValuePair GetKeyValuePair()
{
return new KeyValuePair(_kvpKey, _kvpValue);
}
}
```
In a different class, we then use it like:
```c#
private sealed class ClassDataContractCriticalHelper : DataContract.DataContractCriticalHelper
{
private static readonly MethodInfo s_getKeyValuePairMethod = typeof(KeyValuePairAdapter<,>).GetMethod("GetKeyValuePair", Globals.ScanAllMembers)!;
// ... other code
[RequiresUnreferencedCode(DataContract.SerializerTrimmerWarning)]
private void SetKeyValuePairAdapterFlags(
[DynamicallyAccessedMembers(DataContractPreserveMemberTypes)]
Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfKeyValuePairAdapter)
{
_isKeyValuePairAdapter = true;
_keyValuePairGenericArguments = type.GetGenericArguments();
_keyValuePairCtorInfo = type.GetConstructor(Globals.ScanAllMembers, new Type[] { Globals.TypeOfKeyValuePair.MakeGenericType(_keyValuePairGenericArguments) });
_getKeyValuePairMethodInfo = (MethodInfo)type.GetMemberWithSameMetadataDefinitionAs(s_getKeyValuePairMethod);
}
}
```
The hard reference on the method when assigning it to variable `s_getKeyValuePairMethod ` should cause the method `GetKeyValuePair` on the generic type to get rooted and it's body preserved, but after aggressively linking this code, the linker is correctly detecting the method should be preserved, but it's body is swapped to:

Adding a `[DynamicDependency]` attribute to root the method works around the issue, but there should be no difference between using the `DynamicDependency` attribute and using reflection to depend on a method.
cc: @eerhardt @vitek-karas @sbomer
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.