-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Open
Labels
area-TypeSystem-coreclruntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
Description
Description
Note: this is fixed in .NET 10 bug exists in .NET 8.0.415 and .NET 9.0.307
When a readonly record struct static field references another readonly record struct the types won't load and a ReflectionTypeLoadException is thrown when attempting to use Assembly.GetTypes.
Reproduction Steps
Files and contents:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework><!-- or net8.0 -->
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>// See https://aka.ms/new-console-template for more information
Console.WriteLine("Listing types in current assembly:");
foreach (var type in typeof(Program).Assembly.GetTypes())
{
Console.WriteLine(type.FullName);
}namespace TypeLoadBug;
internal readonly record struct QuestionTrigger(string QuestionId, int AnswerId) {
public static readonly QuestionTriggerList NoTriggers = default;
}
internal readonly record struct QuestionTriggerList(QuestionTrigger Trigger1, QuestionTrigger Trigger2, QuestionTrigger Trigger3) : IEnumerable<QuestionTrigger> {
public IEnumerator<QuestionTrigger> GetEnumerator() {
if (this.Trigger1 != default) yield return this.Trigger1;
if (this.Trigger2 != default) yield return this.Trigger2;
if (this.Trigger3 != default) yield return this.Trigger3;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => this.GetEnumerator();
public static QuestionTriggerList Create((string? QuestionId, int? AnswerId) trigger1, (string? QuestionId, int? AnswerId) trigger2, (string? QuestionId, int? AnswerId) trigger3) {
return new QuestionTriggerList(
trigger1.QuestionId is not null && trigger1.AnswerId is not null ? new QuestionTrigger(trigger1.QuestionId, trigger1.AnswerId.Value) : default,
trigger2.QuestionId is not null && trigger2.AnswerId is not null ? new QuestionTrigger(trigger2.QuestionId, trigger2.AnswerId.Value) : default,
trigger3.QuestionId is not null && trigger3.AnswerId is not null ? new QuestionTrigger(trigger3.QuestionId, trigger3.AnswerId.Value) : default
);
}
}Expected behavior
Output:
Listing types in current assembly:
Program
TypeLoadBug.QuestionTrigger
TypeLoadBug.QuestionTriggerList
TypeLoadBug.QuestionTriggerList+<GetEnumerator>d__13
Actual behavior
Output:
Listing types in current assembly:
Unhandled exception. System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Could not load type 'TypeLoadBug.QuestionTrigger' from assembly 'TypeLoadBug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Could not load type 'TypeLoadBug.QuestionTriggerList' from assembly 'TypeLoadBug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Could not load type 'TypeLoadBug.QuestionTrigger' from assembly 'TypeLoadBug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
at System.Reflection.RuntimeModule.GetDefinedTypes()
at System.Reflection.RuntimeModule.GetTypes()
at Program.<Main>$(String[] args) in D:\ProjectsTemp\TypeLoadBug\Program.cs:line 4
System.TypeLoadException: Could not load type 'TypeLoadBug.QuestionTrigger' from assembly 'TypeLoadBug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type 'TypeLoadBug.QuestionTriggerList' from assembly 'TypeLoadBug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
System.TypeLoadException: Could not load type 'TypeLoadBug.QuestionTrigger' from assembly 'TypeLoadBug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Regression?
Unknown
Known Workarounds
Move the static readonly field to the struct of its type.
Configuration
.NET on Windows, happens on 8.0.415 and 9.0.307 SDKs
Other information
No response
Metadata
Metadata
Assignees
Labels
area-TypeSystem-coreclruntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner