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); } }