From 530f6ad829b8a44da2481320326b9fcb4174f113 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Mon, 25 Aug 2025 19:47:03 +0300 Subject: [PATCH 1/4] Obsolete and hide `DynamicDependencyAttribute.Condition`. --- ...ystem.Diagnostics.CodeAnalysis.DynamicDependencyAttribute.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute.cs index 6930625..96385f4 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute.cs @@ -134,6 +134,8 @@ public DynamicDependencyAttribute(global::System.Diagnostics.CodeAnalysis.Dynami /// /// Gets or sets the condition in which the dependency is applicable, e.g. "DEBUG". /// + [global::System.Obsolete("This property is no longer supported.")] + [global::System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public string? Condition { get; set; } } } \ No newline at end of file From 2e115f69e9730f5b695afdff37111570e52b9dde Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Mon, 25 Aug 2025 20:28:23 +0300 Subject: [PATCH 2/4] Copy .NET 10 attribute sources from `dotnet/runtime`. --- ...vices.CompilerLoweringPreserveAttribute.cs | 28 ++++++++++ ...mpilerServices.ExtensionMarkerAttribute.cs | 24 +++++++++ ...sis.DynamicallyAccessedMembersAttribute.cs | 1 + ...odeAnalysis.UnsafeAccessorTypeAttribute.cs | 53 +++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.cs create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.cs new file mode 100644 index 0000000..a4816d2 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.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 +{ + /// + /// When applied to an attribute class, instructs the compiler to flow applications of that attribute, + /// from source code down to compiler-generated symbols. This can help IL-based analysis tools. + /// + /// + /// One example where this attribute applies is in C# primary constructor parameters. If an attribute + /// marked with gets applied to a primary constructor + /// parameter, the attribute will also be applied to any compiler-generated fields storing that parameter. + /// + [AttributeUsage(AttributeTargets.Class, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class CompilerLoweringPreserveAttribute : Attribute + { + /// + /// Initializes a new instance of the class. + /// + public CompilerLoweringPreserveAttribute() { } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs new file mode 100644 index 0000000..c44dd6c --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; + +namespace System.Runtime.CompilerServices +{ + /// + /// This attribute is used to mark extension members and associate them with a specific marker type (which provides detailed information about an extension block and its receiver parameter). + /// This attribute should not be used by developers in source code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] + public sealed class ExtensionMarkerAttribute : Attribute + { + /// Initializes a new instance of the class. + /// The name of the marker type this extension member is associated with. + public ExtensionMarkerAttribute(string name) + => Name = name; + + /// The name of the marker type this extension member is associated with. + public string Name { get; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute.cs index 6edb6e2..5c3905e 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute.cs @@ -43,6 +43,7 @@ namespace System.Diagnostics.CodeAnalysis [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] [global::Microsoft.CodeAnalysis.Embedded] [global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")] + [global::System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute] internal sealed class DynamicallyAccessedMembersAttribute : global::System.Attribute { /// diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs new file mode 100644 index 0000000..dabcac7 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs @@ -0,0 +1,53 @@ +// 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 access to an inaccessible type. + /// + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = false)] + public sealed class UnsafeAccessorTypeAttribute : Attribute + { + /// + /// Instantiates an providing access to a type supplied by . + /// + /// A fully qualified or partially qualified type name. + /// + /// is expected to follow the same rules as if it were being + /// passed to . When unbound generics are involved they + /// should follow the IL syntax of referencing a type or method generic variables using + /// the syntax of !N or !!N respectively, where N is the zero-based index of the + /// generic parameters. The generic rules defined for + /// apply to this attribute as well, meaning the arity and type of generic parameter must match + /// the target type. + /// + /// This attribute only has behavior on parameters or return values of methods marked with . + /// + /// This attribute should only be applied to parameters or return types of methods that are + /// typed as follows: + /// + ///
    + ///
  • References should be typed as object.
  • + ///
  • Byref arguments should be typed with in, ref, or out to object.
  • + ///
  • Unmanaged pointers should be typed as void*.
  • + ///
  • Byref arguments to reference types or arrays should be typed with in, ref, or out to object.
  • + ///
  • Byref arguments to unmanaged pointer types should be typed with in, ref, or out to void*.
  • + ///
+ /// + /// Value types are not supported. + /// + /// Due to lack of variance for byrefs, returns involving byrefs are not supported. This + /// specifically means that accessors for fields of inaccessible types are not supported. + ///
+ public UnsafeAccessorTypeAttribute(string typeName) + { + TypeName = typeName; + } + + /// + /// Fully qualified or partially qualified type name to target. + /// + public string TypeName { get; } + } +} \ No newline at end of file From 04f53826f982d9c72aea596e6190a8fd31d0fe90 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Mon, 25 Aug 2025 20:45:28 +0300 Subject: [PATCH 3/4] Adapt the attributes to the codebase's standards. --- ...vices.CompilerLoweringPreserveAttribute.cs | 19 ++++++++------- ...mpilerServices.ExtensionMarkerAttribute.cs | 24 +++++++++++++++---- ...odeAnalysis.UnsafeAccessorTypeAttribute.cs | 21 ++++++++++++---- 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.cs index a4816d2..6a54468 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute.cs @@ -1,3 +1,7 @@ +// +#pragma warning disable +#nullable enable annotations + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -9,19 +13,16 @@ namespace System.Runtime.CompilerServices ///
/// /// One example where this attribute applies is in C# primary constructor parameters. If an attribute - /// marked with gets applied to a primary constructor + /// marked with gets applied to a primary constructor /// parameter, the attribute will also be applied to any compiler-generated fields storing that parameter. /// - [AttributeUsage(AttributeTargets.Class, Inherited = false)] -#if SYSTEM_PRIVATE_CORELIB - public -#else - internal -#endif - sealed class CompilerLoweringPreserveAttribute : Attribute + [global::System.AttributeUsage(global::System.AttributeTargets.Class, Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::Microsoft.CodeAnalysis.Embedded] + internal sealed class CompilerLoweringPreserveAttribute : global::System.Attribute { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// public CompilerLoweringPreserveAttribute() { } } diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs index c44dd6c..74401fd 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/LanguageSupport/System.Runtime.CompilerServices.ExtensionMarkerAttribute.cs @@ -1,3 +1,7 @@ +// +#pragma warning disable +#nullable enable annotations + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -9,11 +13,23 @@ namespace System.Runtime.CompilerServices /// This attribute is used to mark extension members and associate them with a specific marker type (which provides detailed information about an extension block and its receiver parameter). /// This attribute should not be used by developers in source code. /// - [EditorBrowsable(EditorBrowsableState.Never)] - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] - public sealed class ExtensionMarkerAttribute : Attribute + [global::System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)] + [global::System.AttributeUsage( + global::System.AttributeTargets.Class | + global::System.AttributeTargets.Struct | + global::System.AttributeTargets.Enum | + global::System.AttributeTargets.Method | + global::System.AttributeTargets.Property | + global::System.AttributeTargets.Field | + global::System.AttributeTargets.Event | + global::System.AttributeTargets.Interface | + global::System.AttributeTargets.Delegate, + Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::Microsoft.CodeAnalysis.Embedded] + internal sealed class ExtensionMarkerAttribute : global::System.Attribute { - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// The name of the marker type this extension member is associated with. public ExtensionMarkerAttribute(string name) => Name = name; diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs index dabcac7..ef363d2 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.UnsafeAccessorTypeAttribute.cs @@ -1,3 +1,7 @@ +// +#pragma warning disable +#nullable enable annotations + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -6,8 +10,15 @@ namespace System.Runtime.CompilerServices /// /// Provides access to an inaccessible type. /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = false)] - public sealed class UnsafeAccessorTypeAttribute : Attribute + [global::System.AttributeUsage( + global::System.AttributeTargets.Parameter | + global::System.AttributeTargets.ReturnValue, + AllowMultiple = false, + Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::Microsoft.CodeAnalysis.Embedded] + [global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")] + internal sealed class UnsafeAccessorTypeAttribute : global::System.Attribute { /// /// Instantiates an providing access to a type supplied by . @@ -15,14 +26,14 @@ public sealed class UnsafeAccessorTypeAttribute : Attribute /// A fully qualified or partially qualified type name. /// /// is expected to follow the same rules as if it were being - /// passed to . When unbound generics are involved they + /// passed to . When unbound generics are involved they /// should follow the IL syntax of referencing a type or method generic variables using /// the syntax of !N or !!N respectively, where N is the zero-based index of the - /// generic parameters. The generic rules defined for + /// generic parameters. The generic rules defined for /// apply to this attribute as well, meaning the arity and type of generic parameter must match /// the target type. /// - /// This attribute only has behavior on parameters or return values of methods marked with . + /// This attribute only has behavior on parameters or return values of methods marked with . /// /// This attribute should only be applied to parameters or return types of methods that are /// typed as follows: From 35ae5369e3cc0d78f324a30a4ace115c41ce64ad Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Mon, 25 Aug 2025 20:52:47 +0300 Subject: [PATCH 4/4] Update README.md files. --- README.md | 3 +++ src/PolySharp.Package/README.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 3e65b86..8e150e3 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[OverloadResolutionPriority]` (needed for [overload resolution priority](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#overload-resolution-priority)) - `[ParamsCollection]` (needed for [params collection](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#params-collections)) - `[ConstantExpected]` (see [proposal](https://github.com/dotnet/runtime/issues/33771)) +- `[CompilerLoweringPreserve]` (see [proposal](https://github.com/dotnet/runtime/issues/103430)) +- `[ExtensionMarker]` (needed for [extensions](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#extension-members)) To leverage them, make sure to bump your C# language version. You can do this by setting the `` MSBuild property in your project. For instance, by adding `13.0` (or your desired C# version) to the first `` of your .csproj file. For more info on this, [see here](https://sergiopedri.medium.com/enabling-and-using-c-9-features-on-older-and-unsupported-runtimes-ce384d8debb), but remember that you don't need to manually copy polyfills anymore: simply adding a reference to **PolySharp** will do this for you automatically. @@ -84,6 +86,7 @@ It also includes the following optional runtime-supported polyfills: - `[FeatureGuard]` - `[FeatureSwitchDefinition]` - `[WasmImportLinkage]` (see [here](https://github.com/dotnet/runtime/pull/93823)) +- `[UnsafeAccessorType]` (see [here](https://github.com/dotnet/runtime/issues/90081)) # Options ⚙️ diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index 0cacf88..fc41674 100644 --- a/src/PolySharp.Package/README.md +++ b/src/PolySharp.Package/README.md @@ -53,6 +53,8 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[OverloadResolutionPriority]` (needed for [overload resolution priority](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#overload-resolution-priority)) - `[ParamsCollection]` (needed for [params collection](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#params-collections)) - `[ConstantExpected]` (see [proposal](https://github.com/dotnet/runtime/issues/33771)) +- `[CompilerLoweringPreserve]` (see [proposal](https://github.com/dotnet/runtime/issues/103430)) +- `[ExtensionMarker]` (needed for [extensions](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#extension-members)) To leverage them, make sure to bump your C# language version. You can do this by setting the `` MSBuild property in your project. For instance, by adding `13.0` (or your desired C# version) to the first `` of your .csproj file. For more info on this, [see here](https://sergiopedri.medium.com/enabling-and-using-c-9-features-on-older-and-unsupported-runtimes-ce384d8debb), but remember that you don't need to manually copy polyfills anymore: simply adding a reference to **PolySharp** will do this for you automatically. @@ -82,6 +84,7 @@ It also includes the following optional runtime-supported polyfills: - `[FeatureGuard]` - `[FeatureSwitchDefinition]` - `[WasmImportLinkage]` (see [here](https://github.com/dotnet/runtime/pull/93823)) +- `[UnsafeAccessorType]` (see [here](https://github.com/dotnet/runtime/issues/90081)) # Options ⚙️