diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 5467cf247a4d0e..2c48c4cba7ffd1 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -897,6 +897,7 @@
+
@@ -938,6 +939,7 @@
+
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
new file mode 100644
index 00000000000000..71a88be48a6a33
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Runtime.CompilerServices
+{
+ ///
+ /// Provides a common interface for accessing the contents of a union type at runtime.
+ ///
+ ///
+ ///
+ /// The C# compiler automatically implements this interface on types generated by union declarations.
+ /// User-defined types annotated with may also implement this interface
+ /// to provide runtime access to the union's value. Implementing this interface is not required
+ /// for union behaviors provided by the compiler.
+ ///
+ ///
+ ///
+ public interface IUnion
+ {
+ ///
+ /// Gets the value contained in the union, or if the union has no value.
+ ///
+ ///
+ /// The current value of the union as one of its case types, or .
+ ///
+ object? Value { get; }
+ }
+}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
new file mode 100644
index 00000000000000..e1e6ea64ebfeee
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Runtime.CompilerServices
+{
+ ///
+ /// Indicates that a class or struct is a union type, enabling compiler support for union behaviors.
+ ///
+ ///
+ ///
+ /// Any class or struct annotated with this attribute is recognized by the C# compiler as a union type.
+ /// Union types may support behaviors such as implicit conversions from case types, pattern matching
+ /// that unwraps the union's contents, and switch exhaustiveness checking.
+ ///
+ ///
+ ///
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
+ public sealed class UnionAttribute : Attribute
+ {
+ }
+}
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index abfa9d8f41fb46..1e205d855b5d0a 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -14063,6 +14063,10 @@ public partial interface ITuple
object? this[int index] { get; }
int Length { get; }
}
+ public partial interface IUnion
+ {
+ object? Value { get; }
+ }
public enum LoadHint
{
Default = 0,
@@ -14489,6 +14493,11 @@ public sealed partial class UnsafeValueTypeAttribute : System.Attribute
{
public UnsafeValueTypeAttribute() { }
}
+ [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple=false, Inherited=false)]
+ public sealed partial class UnionAttribute : System.Attribute
+ {
+ public UnionAttribute() { }
+ }
public readonly partial struct ValueTaskAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion
{
private readonly object _dummy;
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs
index 431c72b61c7ce6..a55efd31bae16f 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs
@@ -426,5 +426,18 @@ public static void OverloadResolutionPriorityAttributeTests()
var attr = new OverloadResolutionPriorityAttribute(42);
Assert.Equal(42, attr.Priority);
}
+
+ [Fact]
+ public static void UnionAttributeTests()
+ {
+ var attr = new UnionAttribute();
+ Assert.NotNull(attr);
+
+ var usage = (AttributeUsageAttribute)Attribute.GetCustomAttribute(typeof(UnionAttribute), typeof(AttributeUsageAttribute))!;
+ Assert.Equal(AttributeTargets.Class | AttributeTargets.Struct, usage.ValidOn);
+ Assert.False(usage.AllowMultiple);
+ Assert.False(usage.Inherited);
+ }
+
}
}