diff --git a/src/TypeSystem/tests/CoreTestAssembly/CoreTestAssembly.csproj b/src/TypeSystem/tests/CoreTestAssembly/CoreTestAssembly.csproj
index 2bda7169d8d..6ea6dc9a4b3 100644
--- a/src/TypeSystem/tests/CoreTestAssembly/CoreTestAssembly.csproj
+++ b/src/TypeSystem/tests/CoreTestAssembly/CoreTestAssembly.csproj
@@ -32,6 +32,7 @@
+
diff --git a/src/TypeSystem/tests/CoreTestAssembly/StaticFieldLayout.cs b/src/TypeSystem/tests/CoreTestAssembly/StaticFieldLayout.cs
new file mode 100644
index 00000000000..68bb885bb6c
--- /dev/null
+++ b/src/TypeSystem/tests/CoreTestAssembly/StaticFieldLayout.cs
@@ -0,0 +1,66 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+
+#pragma warning disable 169
+
+namespace StaticFieldLayout
+{
+ struct NoPointers
+ {
+ static int int1;
+ static byte byte1;
+ static char char1;
+ }
+
+ struct StillNoPointers
+ {
+ NoPointers noPointers1;
+ static bool bool1;
+ }
+
+ class ClassNoPointers
+ {
+ static int int1;
+ static byte byte1;
+ static char char1;
+ }
+
+ struct HasPointers
+ {
+ bool bool1;
+ static string string1;
+ static ClassNoPointers class1;
+ char char1;
+ }
+
+ class MixPointersAndNonPointers
+ {
+ static string string1;
+ static int int1;
+ static ClassNoPointers class1;
+ static int int2;
+ static string string2;
+ }
+
+ class EnsureInheritanceResetsStaticOffsets : MixPointersAndNonPointers
+ {
+ static int int3;
+ static string string3;
+ }
+
+ class RvaTestClass
+ {
+ static void RvaTest()
+ {
+ int[] foo = new int[] { 0, 1, 2, 3, 4, 45, 5, 5 };
+ }
+
+ }
+
+ struct StaticSelfRef
+ {
+ static StaticSelfRef selfRef1;
+ }
+}
diff --git a/src/TypeSystem/tests/StaticFieldLayoutTests.cs b/src/TypeSystem/tests/StaticFieldLayoutTests.cs
new file mode 100644
index 00000000000..d203803c8b8
--- /dev/null
+++ b/src/TypeSystem/tests/StaticFieldLayoutTests.cs
@@ -0,0 +1,230 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+
+using Internal.TypeSystem.Ecma;
+using Internal.TypeSystem;
+
+using Xunit;
+
+namespace TypeSystemTests
+{
+ public class StaticFieldLayoutTests
+ {
+ TestTypeSystemContext _context;
+ EcmaModule _testModule;
+
+ public StaticFieldLayoutTests()
+ {
+ _context = new TestTypeSystemContext(TargetArchitecture.X64);
+ var systemModule = _context.CreateModuleForSimpleName("CoreTestAssembly");
+ _context.SetSystemModule(systemModule);
+
+ _testModule = systemModule;
+ }
+
+ [Fact]
+ public void TestNoPointers()
+ {
+ MetadataType t = _testModule.GetType("StaticFieldLayout", "NoPointers");
+
+ foreach (var field in t.GetFields())
+ {
+ if (!field.IsStatic)
+ continue;
+
+ switch (field.Name)
+ {
+ case "int1":
+ Assert.Equal(0, field.Offset);
+ break;
+ case "byte1":
+ Assert.Equal(4, field.Offset);
+ break;
+ case "char1":
+ Assert.Equal(6, field.Offset);
+ break;
+ default:
+ throw new Exception(field.Name);
+ }
+ }
+ }
+
+ [Fact]
+ public void TestStillNoPointers()
+ {
+ //
+ // Test that static offsets ignore instance fields preceeding them
+ //
+
+ MetadataType t = _testModule.GetType("StaticFieldLayout", "StillNoPointers");
+
+ foreach (var field in t.GetFields())
+ {
+ if (!field.IsStatic)
+ continue;
+
+ switch (field.Name)
+ {
+ case "bool1":
+ Assert.Equal(0, field.Offset);
+ break;
+ default:
+ throw new Exception(field.Name);
+ }
+ }
+ }
+
+ [Fact]
+ public void TestClassNoPointers()
+ {
+ //
+ // Ensure classes behave the same as structs when containing statics
+ //
+
+ MetadataType t = _testModule.GetType("StaticFieldLayout", "ClassNoPointers");
+
+ foreach (var field in t.GetFields())
+ {
+ if (!field.IsStatic)
+ continue;
+
+ switch (field.Name)
+ {
+ case "int1":
+ Assert.Equal(0, field.Offset);
+ break;
+ case "byte1":
+ Assert.Equal(4, field.Offset);
+ break;
+ case "char1":
+ Assert.Equal(6, field.Offset);
+ break;
+ default:
+ throw new Exception(field.Name);
+ }
+ }
+ }
+
+ [Fact]
+ public void TestHasPointers()
+ {
+ //
+ // Test a struct containing static types with pointers
+ //
+
+ MetadataType t = _testModule.GetType("StaticFieldLayout", "HasPointers");
+
+ foreach (var field in t.GetFields())
+ {
+ if (!field.IsStatic)
+ continue;
+
+ switch (field.Name)
+ {
+ case "string1":
+ Assert.Equal(0, field.Offset);
+ break;
+ case "class1":
+ Assert.Equal(8, field.Offset);
+ break;
+ default:
+ throw new Exception(field.Name);
+ }
+ }
+ }
+
+ [Fact]
+ public void TestMixPointersAndNonPointers()
+ {
+ //
+ // Test that static fields with GC pointers get separate offsets from non-GC fields
+ //
+
+ MetadataType t = _testModule.GetType("StaticFieldLayout", "MixPointersAndNonPointers");
+
+ foreach (var field in t.GetFields())
+ {
+ if (!field.IsStatic)
+ continue;
+
+ switch (field.Name)
+ {
+ case "string1":
+ Assert.Equal(0, field.Offset);
+ break;
+ case "int1":
+ Assert.Equal(0, field.Offset);
+ break;
+ case "class1":
+ Assert.Equal(8, field.Offset);
+ break;
+ case "int2":
+ Assert.Equal(4, field.Offset);
+ break;
+ case "string2":
+ Assert.Equal(16, field.Offset);
+ break;
+ default:
+ throw new Exception(field.Name);
+ }
+ }
+ }
+
+ [Fact]
+ public void TestEnsureInheritanceResetsStaticOffsets()
+ {
+ //
+ // Test that when inheriting a class with static fields, the derived slice's static fields
+ // are again offset from 0
+ //
+
+ MetadataType t = _testModule.GetType("StaticFieldLayout", "EnsureInheritanceResetsStaticOffsets");
+
+ foreach (var field in t.GetFields())
+ {
+ if (!field.IsStatic)
+ continue;
+
+ switch (field.Name)
+ {
+ case "int3":
+ Assert.Equal(0, field.Offset);
+ break;
+ case "string3":
+ Assert.Equal(0, field.Offset);
+ break;
+ default:
+ throw new Exception(field.Name);
+ }
+ }
+ }
+
+ [Fact]
+ public void TestStaticSelfRef()
+ {
+ //
+ // Test that we can load a struct which has a static field referencing itself without
+ // going into an infinite loop
+ //
+
+ MetadataType t = _testModule.GetType("StaticFieldLayout", "StaticSelfRef");
+
+ foreach (var field in t.GetFields())
+ {
+ if (!field.IsStatic)
+ continue;
+
+ switch (field.Name)
+ {
+ case "selfRef1":
+ Assert.Equal(0, field.Offset);
+ break;
+ default:
+ throw new Exception(field.Name);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/TypeSystem/tests/TypeSystem.Tests.csproj b/src/TypeSystem/tests/TypeSystem.Tests.csproj
index c4e06dc0eed..b01fd936660 100644
--- a/src/TypeSystem/tests/TypeSystem.Tests.csproj
+++ b/src/TypeSystem/tests/TypeSystem.Tests.csproj
@@ -35,6 +35,7 @@
+