From 2ce8283660e0424a28a432e1b0703d84c1839002 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 12:45:28 +0000
Subject: [PATCH 01/11] Initial plan
From 14dfebabbd6d01ee21ee84fb149a2592f2c21746 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 13:30:56 +0000
Subject: [PATCH 02/11] Add UnionAttribute and IUnion interface to
System.Runtime.CompilerServices
Implements the approved API proposal:
- UnionAttribute: [AttributeUsage(Class | Struct, AllowMultiple = false)]
- IUnion interface with object? Value property
- Reference assembly entries in System.Runtime
- Unit tests for both types
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/14611c00-c711-45fe-955e-eb95c8903eac
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
---
.../System.Private.CoreLib.Shared.projitems | 2 ++
.../System/Runtime/CompilerServices/IUnion.cs | 16 ++++++++++
.../CompilerServices/UnionAttribute.cs | 13 ++++++++
.../System.Runtime/ref/System.Runtime.cs | 9 ++++++
.../CompilerServices/AttributesTests.cs | 31 +++++++++++++++++++
5 files changed, 71 insertions(+)
create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
create mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
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..e49a199346fd6e
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
@@ -0,0 +1,16 @@
+// 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
+{
+ ///
+ /// Represents a union type.
+ ///
+ public interface IUnion
+ {
+ ///
+ /// Gets the value of the union, 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..f8563d9e917c57
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -0,0 +1,13 @@
+// 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 type is a union type.
+ ///
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
+ public 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..7168ced56ee6c9 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=true)]
+ public 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..3fb40f0ea375cb 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,36 @@ 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);
+ }
+
+ [Fact]
+ public static void IUnionTests()
+ {
+ Assert.True(typeof(IUnion).IsInterface);
+
+ var testUnion = new TestUnion("hello");
+ IUnion union = testUnion;
+ Assert.Equal("hello", union.Value);
+
+ var nullUnion = new TestUnion(null);
+ Assert.Null(((IUnion)nullUnion).Value);
+ }
+
+ [Union]
+ private struct TestUnion : IUnion
+ {
+ public TestUnion(object? value) => Value = value;
+ public object? Value { get; }
+ }
}
}
From 68ee32da515e28b37b3b261f004c6e44cb329339 Mon Sep 17 00:00:00 2001
From: Eirik Tsarpalis
Date: Thu, 16 Apr 2026 16:47:54 +0300
Subject: [PATCH 03/11] Apply suggestion from @eiriktsarpalis
---
.../src/System/Runtime/CompilerServices/UnionAttribute.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
index f8563d9e917c57..e95e213cbeb8f1 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -7,7 +7,7 @@ namespace System.Runtime.CompilerServices
/// Indicates that a type is a union type.
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
- public class UnionAttribute : Attribute
+ public sealed class UnionAttribute : Attribute
{
}
}
From a037949be97e0fd954da277587f0534b2e50f8b8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 14:13:23 +0000
Subject: [PATCH 04/11] Add comprehensive XML documentation for UnionAttribute
and IUnion
- UnionAttribute: documents union behaviors (conversions, matching,
exhaustiveness), basic union pattern requirements, compiler-generated
union declarations, and includes a code example
- IUnion: documents compiler implementation, case type expectations,
and Value property semantics
- Both types cross-reference each other via seealso and link to the
C# unions language proposal
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/4ac1d4a0-9aee-4119-8d28-9af1e14fb22b
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
---
.../System/Runtime/CompilerServices/IUnion.cs | 25 +++++++++-
.../CompilerServices/UnionAttribute.cs | 50 ++++++++++++++++++-
2 files changed, 72 insertions(+), 3 deletions(-)
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
index e49a199346fd6e..35aa85920f17ef 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
@@ -4,13 +4,34 @@
namespace System.Runtime.CompilerServices
{
///
- /// Represents a union type.
+ /// 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 participate in union behaviors such as implicit union conversions, union pattern matching,
+ /// and switch exhaustiveness checking.
+ ///
+ ///
+ /// The property is expected to return or a value of
+ /// one of the union's case types. A union's case types are determined by its single-parameter
+ /// constructors (or static Create factory methods when a union member provider is used).
+ ///
+ ///
+ /// For more information, see the
+ /// C# unions proposal.
+ ///
+ ///
+ ///
public interface IUnion
{
///
- /// Gets the value of the union, or .
+ /// 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
index e95e213cbeb8f1..f62352cb9a43b9 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -4,8 +4,56 @@
namespace System.Runtime.CompilerServices
{
///
- /// Indicates that a type is a union type.
+ /// 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 support the following behaviors:
+ ///
+ ///
+ /// -
+ /// Implicit conversions from each case type to the union type (union conversions).
+ ///
+ /// -
+ /// Pattern matching that automatically unwraps the union's contents, applying patterns to
+ /// the underlying value rather than to the union wrapper itself (union matching).
+ ///
+ /// -
+ /// Switch exhaustiveness checking that considers a switch complete when all case types
+ /// have been matched, without requiring a fallback case (union exhaustiveness).
+ ///
+ ///
+ ///
+ /// A union type must follow the basic union pattern: it must have at least one single-parameter
+ /// public constructor (or static Create factory method when using a union member provider),
+ /// and a public Value property of type . The parameter types of these
+ /// constructors or factory methods determine the union's case types. Implementing
+ /// is optional but recommended, as it provides runtime access to
+ /// the union's value and is automatically implemented by compiler-generated union declarations.
+ ///
+ ///
+ /// The C# union declaration syntax automatically generates a struct annotated with this
+ /// attribute and implementing .
+ ///
+ ///
+ /// For more information, see the
+ /// C# unions proposal.
+ ///
+ ///
+ ///
+ /// The following example shows a manually declared union type:
+ ///
+ /// [Union]
+ /// public struct Pet : IUnion
+ /// {
+ /// public Pet(Cat value) => Value = value;
+ /// public Pet(Dog value) => Value = value;
+ /// public object? Value { get; }
+ /// }
+ ///
+ ///
+ ///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
public sealed class UnionAttribute : Attribute
{
From 1b5fa60bc00f5428632edf5bdb0675db97dc5ffa Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 14:38:21 +0000
Subject: [PATCH 05/11] Document Value property per language spec; seal
UnionAttribute in ref assembly
- Added remarks to IUnion.Value explaining its role in union pattern
matching and the well-formedness invariants (soundness, stability)
from the C# unions proposal
- Updated ref assembly to mark UnionAttribute as sealed, matching the
implementation
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/8d2b3956-eedf-4a7d-a997-54ad5689c1c8
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
---
.../System/Runtime/CompilerServices/IUnion.cs | 22 +++++++++++++++++++
.../System.Runtime/ref/System.Runtime.cs | 2 +-
2 files changed, 23 insertions(+), 1 deletion(-)
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
index 35aa85920f17ef..50379ccb5075b7 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
@@ -32,6 +32,28 @@ public interface IUnion
///
/// The current value of the union as one of its case types, or .
///
+ ///
+ ///
+ /// The property provides access to the contents of a union regardless of the
+ /// case type. The compiler uses this property when performing union pattern matching: patterns applied
+ /// to a union value are implicitly applied to its property rather than to the
+ /// union wrapper itself.
+ ///
+ ///
+ /// The property is expected to satisfy the following well-formedness invariants:
+ ///
+ ///
+ /// -
+ /// Soundness: always evaluates to or to an instance of
+ /// one of the union's case types, including for the default value of the union type.
+ ///
+ /// -
+ /// Stability: if the union is created from a case type value, returns that value
+ /// (or ). If the union is created from ,
+ /// returns .
+ ///
+ ///
+ ///
object? Value { get; }
}
}
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index 7168ced56ee6c9..890b8055d485a0 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -14494,7 +14494,7 @@ public sealed partial class UnsafeValueTypeAttribute : System.Attribute
public UnsafeValueTypeAttribute() { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple=false, Inherited=true)]
- public partial class UnionAttribute : System.Attribute
+ public sealed partial class UnionAttribute : System.Attribute
{
public UnionAttribute() { }
}
From c2d4e07ea139a9f7f4abc1cb592f60debc0ac335 Mon Sep 17 00:00:00 2001
From: Eirik Tsarpalis
Date: Thu, 16 Apr 2026 17:42:54 +0300
Subject: [PATCH 06/11] Update
src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../src/System/Runtime/CompilerServices/UnionAttribute.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
index f62352cb9a43b9..e93798d7a16670 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -55,7 +55,7 @@ namespace System.Runtime.CompilerServices
///
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
- public sealed class UnionAttribute : Attribute
+ public class UnionAttribute : Attribute
{
}
}
From 6d1d2bcef033915078d11c674154ac32c50ffbaa Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 15:10:15 +0000
Subject: [PATCH 07/11] Remove proposal links and simplify XML docs to avoid
naming specific patterns
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/7354c2b8-e3f0-4226-bbaf-c08390c861c0
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
---
.../System/Runtime/CompilerServices/IUnion.cs | 30 +++--------------
.../CompilerServices/UnionAttribute.cs | 32 +++----------------
2 files changed, 8 insertions(+), 54 deletions(-)
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
index 50379ccb5075b7..8781f0f545edcf 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
@@ -10,17 +10,12 @@ namespace System.Runtime.CompilerServices
///
/// The C# compiler automatically implements this interface on types generated by union declarations.
/// User-defined types annotated with may also implement this interface
- /// to participate in union behaviors such as implicit union conversions, union pattern matching,
+ /// to participate in union behaviors such as implicit conversions, pattern matching,
/// and switch exhaustiveness checking.
///
///
/// The property is expected to return or a value of
- /// one of the union's case types. A union's case types are determined by its single-parameter
- /// constructors (or static Create factory methods when a union member provider is used).
- ///
- ///
- /// For more information, see the
- /// C# unions proposal.
+ /// one of the union's case types.
///
///
///
@@ -33,26 +28,9 @@ public interface IUnion
/// The current value of the union as one of its case types, or .
///
///
- ///
/// The property provides access to the contents of a union regardless of the
- /// case type. The compiler uses this property when performing union pattern matching: patterns applied
- /// to a union value are implicitly applied to its property rather than to the
- /// union wrapper itself.
- ///
- ///
- /// The property is expected to satisfy the following well-formedness invariants:
- ///
- ///
- /// -
- /// Soundness: always evaluates to or to an instance of
- /// one of the union's case types, including for the default value of the union type.
- ///
- /// -
- /// Stability: if the union is created from a case type value, returns that value
- /// (or ). If the union is created from ,
- /// returns .
- ///
- ///
+ /// case type. The property is expected to always evaluate to or to an instance of
+ /// one of the union's case types.
///
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
index e93798d7a16670..787373fb7b127c 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -9,37 +9,13 @@ namespace System.Runtime.CompilerServices
///
///
/// Any class or struct annotated with this attribute is recognized by the C# compiler as a union type.
- /// Union types support the following behaviors:
+ /// Union types may support behaviors such as implicit conversions from case types, pattern matching
+ /// that unwraps the union's contents, and switch exhaustiveness checking.
///
- ///
- /// -
- /// Implicit conversions from each case type to the union type (union conversions).
- ///
- /// -
- /// Pattern matching that automatically unwraps the union's contents, applying patterns to
- /// the underlying value rather than to the union wrapper itself (union matching).
- ///
- /// -
- /// Switch exhaustiveness checking that considers a switch complete when all case types
- /// have been matched, without requiring a fallback case (union exhaustiveness).
- ///
- ///
///
- /// A union type must follow the basic union pattern: it must have at least one single-parameter
- /// public constructor (or static Create factory method when using a union member provider),
- /// and a public Value property of type . The parameter types of these
- /// constructors or factory methods determine the union's case types. Implementing
- /// is optional but recommended, as it provides runtime access to
+ /// Implementing is optional but recommended, as it provides runtime access to
/// the union's value and is automatically implemented by compiler-generated union declarations.
///
- ///
- /// The C# union declaration syntax automatically generates a struct annotated with this
- /// attribute and implementing .
- ///
- ///
- /// For more information, see the
- /// C# unions proposal.
- ///
///
///
/// The following example shows a manually declared union type:
@@ -55,7 +31,7 @@ namespace System.Runtime.CompilerServices
///
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
- public class UnionAttribute : Attribute
+ public sealed class UnionAttribute : Attribute
{
}
}
From 44d9a8f9ac5d4b20bbae9b97252b25e5fc13779b Mon Sep 17 00:00:00 2001
From: Eirik Tsarpalis
Date: Thu, 16 Apr 2026 18:38:35 +0300
Subject: [PATCH 08/11] Manual cleanup of XML comments
---
.../System/Runtime/CompilerServices/IUnion.cs | 9 ---------
.../Runtime/CompilerServices/UnionAttribute.cs | 16 ----------------
2 files changed, 25 deletions(-)
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
index 8781f0f545edcf..4ef04ed15d3d46 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
@@ -13,10 +13,6 @@ namespace System.Runtime.CompilerServices
/// to participate in union behaviors such as implicit conversions, pattern matching,
/// and switch exhaustiveness checking.
///
- ///
- /// The property is expected to return or a value of
- /// one of the union's case types.
- ///
///
///
public interface IUnion
@@ -27,11 +23,6 @@ public interface IUnion
///
/// The current value of the union as one of its case types, or .
///
- ///
- /// The property provides access to the contents of a union regardless of the
- /// case type. The property is expected to always evaluate to or to an instance of
- /// one of the union's case types.
- ///
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
index 787373fb7b127c..86fd9c897f323f 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -12,23 +12,7 @@ namespace System.Runtime.CompilerServices
/// Union types may support behaviors such as implicit conversions from case types, pattern matching
/// that unwraps the union's contents, and switch exhaustiveness checking.
///
- ///
- /// Implementing is optional but recommended, as it provides runtime access to
- /// the union's value and is automatically implemented by compiler-generated union declarations.
- ///
///
- ///
- /// The following example shows a manually declared union type:
- ///
- /// [Union]
- /// public struct Pet : IUnion
- /// {
- /// public Pet(Cat value) => Value = value;
- /// public Pet(Dog value) => Value = value;
- /// public object? Value { get; }
- /// }
- ///
- ///
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
public sealed class UnionAttribute : Attribute
From ed258116cd9aac3727774d6c0b999e9a27e6c2fb Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 15:46:42 +0000
Subject: [PATCH 09/11] Remove IUnionTests and TestUnion test class per review
feedback
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/97c5c3f7-5d49-420a-bc05-dc0e3f952981
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
---
.../CompilerServices/AttributesTests.cs | 19 -------------------
1 file changed, 19 deletions(-)
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 3fb40f0ea375cb..2c172990475b41 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
@@ -438,24 +438,5 @@ public static void UnionAttributeTests()
Assert.False(usage.AllowMultiple);
}
- [Fact]
- public static void IUnionTests()
- {
- Assert.True(typeof(IUnion).IsInterface);
-
- var testUnion = new TestUnion("hello");
- IUnion union = testUnion;
- Assert.Equal("hello", union.Value);
-
- var nullUnion = new TestUnion(null);
- Assert.Null(((IUnion)nullUnion).Value);
- }
-
- [Union]
- private struct TestUnion : IUnion
- {
- public TestUnion(object? value) => Value = value;
- public object? Value { get; }
- }
}
}
From 798d7ab973e7dce560961ca3bea1dc36173426c3 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 17:13:05 +0000
Subject: [PATCH 10/11] Fix IUnion XML docs: implementing interface is not
required for union behaviors
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d12aaafc-9873-46b6-8d57-9347e83bf677
Co-authored-by: AlekseyTs <10522107+AlekseyTs@users.noreply.github.com>
---
.../src/System/Runtime/CompilerServices/IUnion.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
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
index 4ef04ed15d3d46..71a88be48a6a33 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs
@@ -10,8 +10,8 @@ namespace System.Runtime.CompilerServices
///
/// The C# compiler automatically implements this interface on types generated by union declarations.
/// User-defined types annotated with may also implement this interface
- /// to participate in union behaviors such as implicit conversions, pattern matching,
- /// and switch exhaustiveness checking.
+ /// to provide runtime access to the union's value. Implementing this interface is not required
+ /// for union behaviors provided by the compiler.
///
///
///
From 041b73acc3936bc0a927bb316ee1f7f10de2a418 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 16 Apr 2026 17:19:27 +0000
Subject: [PATCH 11/11] =?UTF-8?q?Change=20UnionAttribute=20Inherited=20to?=
=?UTF-8?q?=20false=20=E2=80=94=20derived=20types=20aren't=20unions=20by?=
=?UTF-8?q?=20default?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/97746d3f-15f0-4853-a428-54fd5ac4ba63
Co-authored-by: AlekseyTs <10522107+AlekseyTs@users.noreply.github.com>
---
.../src/System/Runtime/CompilerServices/UnionAttribute.cs | 2 +-
src/libraries/System.Runtime/ref/System.Runtime.cs | 2 +-
.../System/Runtime/CompilerServices/AttributesTests.cs | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
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
index 86fd9c897f323f..e1e6ea64ebfeee 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs
@@ -14,7 +14,7 @@ namespace System.Runtime.CompilerServices
///
///
///
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
+ [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 890b8055d485a0..1e205d855b5d0a 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -14493,7 +14493,7 @@ public sealed partial class UnsafeValueTypeAttribute : System.Attribute
{
public UnsafeValueTypeAttribute() { }
}
- [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple=false, Inherited=true)]
+ [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple=false, Inherited=false)]
public sealed partial class UnionAttribute : System.Attribute
{
public UnionAttribute() { }
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 2c172990475b41..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
@@ -436,6 +436,7 @@ public static void UnionAttributeTests()
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);
}
}