Skip to content

TypeLoadException when a ref struct using explicit layout has fields of type ref struct #111260

Closed
@lithiumtoast

Description

@lithiumtoast

Description

Context: Found in .NET 9 when experimenting with ref struct in P/Invoke scenarios. I want to make it clear that I'm not using "ref fields" but rather only "ref structs"; the fields of the struct are not ref (pointer) but the type is of ref struct (stack-only).

Reproduction Steps

using System;
using System.Runtime.InteropServices;
					
public class Program
{
    [StructLayout(LayoutKind.Explicit, Size = 8, Pack = 8)]
    public ref struct Foo
    {
        [FieldOffset(0)]
        public Bar A;
        [FieldOffset(4)]
        public Bar B;
    }

    public ref struct Bar
    {
        public uint Value;
    }
	
    public static void Main()
    {
	var e = default(Foo);
	e.A.Value = 1;
	e.B.Value = 2;
	Console.WriteLine("1 + 2 = " + (e.A.Value + e.B.Value));
    }
}

Expected behavior

A ref struct of explicit layout can have fields that are positioned using FieldOffset attribute where the type of the field is a ref struct without creating a runtime exception.

Actual behavior

When a ref struct is using explicit struct layout, a System.TypeLoadException can occur regarding the field offset of the struct's field which the type is another ref struct.

Unhandled exception. System.TypeLoadException: Could not load type 'Foo' from assembly 'r2oeekw4.exe, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.
   at Program.Main()

Regression?

No response

Known Workarounds

  • Removing the ref from the nested struct.

Configuration

  • .NET 9
  • macOS Ventura 13.6.5
  • Apple M1 (osx-arm64)
  • Not specific to any configuration.

Other information

Hypothesis: The word ref in the context of a struct (stack-only) is confused to be in the context of a field (pointer); the field is mistaken for an object type with rules about field alignment when it's actually a struct.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-TypeSystem-coreclrin-prThere is an active PR which will close this issue when it is merged

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions