Fail to export referenced types in `System.Private.CoreLib` due to `DefaultInterpolatedStringHandler`
Algoryx-NilsHjelte opened this issue · comments
I am getting the following exception during GenerateAssembly
call:
Referenced assembly cannot be found: System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'
This is currently from usage of the type System.Runtime.CompilerServices.DefaultInterpolatedStringHandler
I see references to System.Private.CoreLib
in #139 but that issue is talking about the assemblies in the exported dll, which is a separate issue?
Ok, I have tracked this a bit more, and I see that ILPack use the netstandard
lib as a proxy for System.Private.CoreLib
.Select(assembly => assembly.Name == "System.Private.CoreLib" ? netstandardName : assembly)
The problem is that System.Runtime.CompilerServices.DefaultInterpolatedStringHandler
is not part of netstandard.dll
in .NET 6.0.1.
It looks like DefaultInterpolatedStringHandler
is part of the System.Runtime.CompilerServices.dll
, but this is not referenced by my AssemblyBuilder.
And I see no way of manually adding this reference, the AddAssemblyReference
API is only available in .NET Framework
I have also tried using the GenerateAssembly
overload with IEnumerable<Assembly> referencedDynamicAssembly
parameter, which I have added the required assembly dll:
var additionalReferencedAssemblies = new[] {
AppDomain.CurrentDomain.GetAssemblies().Single(a => a.GetName().Name == "System.Runtime.CompilerServices.Unsafe")
};
but, this referencedDynamicAssembly
is never used in the AssemblyMetadata
constructor when CreateReferencedAssemblies
is called.
Well, I guess this is by design, as the referencedDynamicAssembly
is supposed to contain dynamic assemblies.
Anyway, I am kind of stuck here and not sure how to work around this, except for some local source code workaround in ILPack.
Hi @Algoryx-NilsHjelte, thanks for this detailed report. I can't promise much. However, if you could provide a PR for a code snippet that replicates the problem, it would help a lot. You can have a look at the content of https://github.com/Lokad/ILPack/tree/master/test/TestSubject (which is expected to match https://github.com/Lokad/ILPack/tree/master/test/Lokad.ILPack.Tests ) , and add a test that triggers the failure. This would go a long way to get this fixed.
Hi, I am unable to run the tests locally on my Mac with .NET 6.0.
I was unable to run the netcoreapp2.0
target, and updated all targets locally to net6.0
.
But when I run dotnet test
it just hangs, and event dotnet test --blame
gives no information on what is blocking the tests.
But I have the following minimal example here that demonstrates the bug:
I have tested it in a standalone separate csproj, and not as part of ILPack.Tests
[Fact]
public void TestInterpolatedStrings() {
var assemblyName = new AssemblyName { Name = "MyAssembly" };
var newAssembly = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var newModule = newAssembly.DefineDynamicModule("MyModule");
// Define a type with no namespace
var myType = newModule.DefineType("MyClass", TypeAttributes.Public);
// Define a method to just return a new instance of anonymous type.
var myMethod = myType.DefineMethod("MyMethod", MethodAttributes.Public, typeof(string), Type.EmptyTypes);
var generator = myMethod.GetILGenerator();
var builder = generator.DeclareLocal(typeof(System.Runtime.CompilerServices.DefaultInterpolatedStringHandler));
generator.Emit(OpCodes.Ldloca, builder.LocalIndex);
generator.Emit(OpCodes.Ldc_I4, 0);
generator.Emit(OpCodes.Ldc_I4, 0);
var DefaultInterpolatedStringHandlerConstructorInfo = builder.LocalType.GetConstructor(new[] { typeof(int), typeof(int) })!;
var ToStringAndClearInfo = builder.LocalType.GetMethod("ToStringAndClear", Type.EmptyTypes)!;
generator.Emit(OpCodes.Call, DefaultInterpolatedStringHandlerConstructorInfo);
generator.Emit(OpCodes.Ldloca, builder.LocalIndex);
generator.Emit(OpCodes.Call, ToStringAndClearInfo);
generator.Emit(OpCodes.Ret);
myType.CreateType();
SerializeAndVerifyAssembly(newAssembly, "InterpolatedStringsSerialization.dll");
}
My current workaround in the local ILPack code is to mutate the AssemblyMetadata
constructor using this:
public AssemblyMetadata(Assembly sourceAssembly, IEnumerable<Assembly> referencedDynamicAssemblies)
{
// ...
var a = AppDomain.CurrentDomain.GetAssemblies().Single(a => a.GetName().Name == "System.Runtime.CompilerServices.Unsafe");
// assemblies = assemblies.Append(a.GetName());
AddReferencedAssembly(a.GetName().Name, a.GetName());
_reverseForwardingMap.Add("System.Runtime.CompilerServices.DefaultInterpolatedStringHandler", a.GetName());
CreateReferencedAssemblies(assemblies);
}