Skip to content

Commit 4d06ed1

Browse files
authored
Merge pull request #131 from teo-tsirpanis/net10
Add polyfills for .NET 10 attributes.
2 parents 11526fb + 942f94c commit 4d06ed1

9 files changed

Lines changed: 158 additions & 0 deletions

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Here's an example of some of the new features that **PolySharp** can enable down
5555
- `[OverloadResolutionPriority]` (needed for [overload resolution priority](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#overload-resolution-priority))
5656
- `[ParamsCollection]` (needed for [params collection](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#params-collections))
5757
- `[ConstantExpected]` (see [proposal](https://github.com/dotnet/runtime/issues/33771))
58+
- `[CompilerLoweringPreserve]` (see [proposal](https://github.com/dotnet/runtime/issues/103430))
59+
- `[ExtensionMarker]` (needed for [extensions](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#extension-members))
5860

5961
To leverage them, make sure to bump your C# language version. You can do this by setting the `<LangVersion>` MSBuild property in your project. For instance, by adding `<LangVersion>13.0</LangVersion>` (or your desired C# version) to the first `<PropertyGroup>` 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.
6062

@@ -84,6 +86,7 @@ It also includes the following optional runtime-supported polyfills:
8486
- `[FeatureGuard]`
8587
- `[FeatureSwitchDefinition]`
8688
- `[WasmImportLinkage]` (see [here](https://github.com/dotnet/runtime/pull/93823))
89+
- `[UnsafeAccessorType]` (see [here](https://github.com/dotnet/runtime/issues/90081))
8790

8891
# Options ⚙️
8992

src/PolySharp.Package/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Here's an example of some of the new features that **PolySharp** can enable down
5353
- `[OverloadResolutionPriority]` (needed for [overload resolution priority](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#overload-resolution-priority))
5454
- `[ParamsCollection]` (needed for [params collection](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#params-collections))
5555
- `[ConstantExpected]` (see [proposal](https://github.com/dotnet/runtime/issues/33771))
56+
- `[CompilerLoweringPreserve]` (see [proposal](https://github.com/dotnet/runtime/issues/103430))
57+
- `[ExtensionMarker]` (needed for [extensions](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#extension-members))
5658

5759
To leverage them, make sure to bump your C# language version. You can do this by setting the `<LangVersion>` MSBuild property in your project. For instance, by adding `<LangVersion>13.0</LangVersion>` (or your desired C# version) to the first `<PropertyGroup>` 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.
5860

@@ -82,6 +84,7 @@ It also includes the following optional runtime-supported polyfills:
8284
- `[FeatureGuard]`
8385
- `[FeatureSwitchDefinition]`
8486
- `[WasmImportLinkage]` (see [here](https://github.com/dotnet/runtime/pull/93823))
87+
- `[UnsafeAccessorType]` (see [here](https://github.com/dotnet/runtime/issues/90081))
8588

8689
# Options ⚙️
8790

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// <auto-generated/>
2+
#pragma warning disable
3+
#nullable enable annotations
4+
5+
// Licensed to the .NET Foundation under one or more agreements.
6+
// The .NET Foundation licenses this file to you under the MIT license.
7+
8+
namespace System.Runtime.CompilerServices
9+
{
10+
/// <summary>
11+
/// When applied to an attribute class, instructs the compiler to flow applications of that attribute,
12+
/// from source code down to compiler-generated symbols. This can help IL-based analysis tools.
13+
/// </summary>
14+
/// <remarks>
15+
/// One example where this attribute applies is in C# primary constructor parameters. If an attribute
16+
/// marked with <see cref="global::System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute"/> gets applied to a primary constructor
17+
/// parameter, the attribute will also be applied to any compiler-generated fields storing that parameter.
18+
/// </remarks>
19+
[global::System.AttributeUsage(global::System.AttributeTargets.Class, Inherited = false)]
20+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
21+
[global::Microsoft.CodeAnalysis.Embedded]
22+
internal sealed class CompilerLoweringPreserveAttribute : global::System.Attribute
23+
{
24+
/// <summary>
25+
/// Initializes a new instance of the <see cref="global::System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute"/> class.
26+
/// </summary>
27+
public CompilerLoweringPreserveAttribute()
28+
{
29+
}
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// <auto-generated/>
2+
#pragma warning disable
3+
#nullable enable annotations
4+
5+
// Licensed to the .NET Foundation under one or more agreements.
6+
// The .NET Foundation licenses this file to you under the MIT license.
7+
8+
using System.ComponentModel;
9+
10+
namespace System.Runtime.CompilerServices
11+
{
12+
/// <summary>
13+
/// 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).
14+
/// This attribute should not be used by developers in source code.
15+
/// </summary>
16+
[global::System.ComponentModel.EditorBrowsable(EditorBrowsableState.Never)]
17+
[global::System.AttributeUsage(
18+
global::System.AttributeTargets.Class |
19+
global::System.AttributeTargets.Struct |
20+
global::System.AttributeTargets.Enum |
21+
global::System.AttributeTargets.Method |
22+
global::System.AttributeTargets.Property |
23+
global::System.AttributeTargets.Field |
24+
global::System.AttributeTargets.Event |
25+
global::System.AttributeTargets.Interface |
26+
global::System.AttributeTargets.Delegate,
27+
Inherited = false)]
28+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
29+
[global::Microsoft.CodeAnalysis.Embedded]
30+
internal sealed class ExtensionMarkerAttribute : global::System.Attribute
31+
{
32+
/// <summary>Initializes a new instance of the <see cref="global::System.Runtime.CompilerServices.ExtensionMarkerAttribute"/> class.</summary>
33+
/// <param name="name">The name of the marker type this extension member is associated with.</param>
34+
public ExtensionMarkerAttribute(string name) => Name = name;
35+
36+
/// <summary>The name of the marker type this extension member is associated with.</summary>
37+
public string Name { get; }
38+
}
39+
}

src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ public DynamicDependencyAttribute(global::System.Diagnostics.CodeAnalysis.Dynami
134134
/// <summary>
135135
/// Gets or sets the condition in which the dependency is applicable, e.g. "DEBUG".
136136
/// </summary>
137+
[global::System.Obsolete("This property is no longer supported.")]
138+
[global::System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
137139
public string? Condition { get; set; }
138140
}
139141
}

src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace System.Diagnostics.CodeAnalysis
4040
global::System.AttributeTargets.Interface |
4141
global::System.AttributeTargets.Struct,
4242
Inherited = false)]
43+
[global::System.Runtime.CompilerServices.CompilerLoweringPreserveAttribute]
4344
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
4445
[global::Microsoft.CodeAnalysis.Embedded]
4546
[global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// <auto-generated/>
2+
#pragma warning disable
3+
#nullable enable annotations
4+
5+
// Licensed to the .NET Foundation under one or more agreements.
6+
// The .NET Foundation licenses this file to you under the MIT license.
7+
8+
namespace System.Runtime.CompilerServices
9+
{
10+
/// <summary>
11+
/// Provides access to an inaccessible type.
12+
/// </summary>
13+
[global::System.AttributeUsage(
14+
global::System.AttributeTargets.Parameter |
15+
global::System.AttributeTargets.ReturnValue,
16+
AllowMultiple = false,
17+
Inherited = false)]
18+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
19+
[global::Microsoft.CodeAnalysis.Embedded]
20+
[global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")]
21+
internal sealed class UnsafeAccessorTypeAttribute : global::System.Attribute
22+
{
23+
/// <summary>
24+
/// Instantiates an <see cref="UnsafeAccessorTypeAttribute"/> providing access to a type supplied by <paramref name="typeName"/>.
25+
/// </summary>
26+
/// <param name="typeName">A fully qualified or partially qualified type name.</param>
27+
/// <remarks>
28+
/// <paramref name="typeName"/> is expected to follow the same rules as if it were being
29+
/// passed to <see name="global::System.Type.GetType(global::System.String)"/>. When unbound generics are involved they
30+
/// should follow the IL syntax of referencing a type or method generic variables using
31+
/// the syntax of <c>!N</c> or <c>!!N</c> respectively, where N is the zero-based index of the
32+
/// generic parameters. The generic rules defined for <see cref="global::System.Diagnostics.CodeAnalysis.UnsafeAccessorAttribute"/>
33+
/// apply to this attribute as well, meaning the arity and type of generic parameter must match
34+
/// the target type.
35+
///
36+
/// This attribute only has behavior on parameters or return values of methods marked with <see cref="global::System.Diagnostics.CodeAnalysis.UnsafeAccessorAttribute"/>.
37+
///
38+
/// This attribute should only be applied to parameters or return types of methods that are
39+
/// typed as follows:
40+
///
41+
/// <ul>
42+
/// <li>References should be typed as <lang>object</lang>.</li>
43+
/// <li>Byref arguments should be typed with <lang>in</lang>, <lang>ref</lang>, or <lang>out</lang> to <lang>object</lang>.</li>
44+
/// <li>Unmanaged pointers should be typed as <lang>void*</lang>.</li>
45+
/// <li>Byref arguments to reference types or arrays should be typed with <lang>in</lang>, <lang>ref</lang>, or <lang>out</lang> to <lang>object</lang>.</li>
46+
/// <li>Byref arguments to unmanaged pointer types should be typed with <lang>in</lang>, <lang>ref</lang>, or <lang>out</lang> to <lang>void*</lang>.</li>
47+
/// </ul>
48+
///
49+
/// Value types are not supported.
50+
///
51+
/// Due to lack of variance for byrefs, returns involving byrefs are not supported. This
52+
/// specifically means that accessors for fields of inaccessible types are not supported.
53+
/// </remarks>
54+
public UnsafeAccessorTypeAttribute(string typeName)
55+
{
56+
TypeName = typeName;
57+
}
58+
59+
/// <summary>
60+
/// Fully qualified or partially qualified type name to target.
61+
/// </summary>
62+
public string TypeName { get; }
63+
}
64+
}

tests/PolySharp.Tests/LanguageFeatures.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,15 @@ public static void AnotherCpuIntrinsic([ConstantExpected(Min = 0, Max = 8)] int
301301
{
302302
}
303303
}
304+
305+
[CompilerLoweringPreserve]
306+
internal sealed class TestFlowingAttribute : Attribute;
307+
308+
// Test for '[ExtensionMarker]'
309+
internal static class ExtensionContainer
310+
{
311+
extension(string s)
312+
{
313+
public bool M => s == "PolySharp";
314+
}
315+
}

tests/PolySharp.Tests/RuntimeSupport.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ public void HideMe()
103103

104104
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = nameof(field))]
105105
public static extern ref int GetField(RandomApis obj);
106+
107+
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = nameof(field))]
108+
public static extern ref int GetAnonymousField([UnsafeAccessorType("Foo, PolySharp.ExternalTypes")] object? obj);
106109
}
107110

108111
[InlineArray(16)]

0 commit comments

Comments
 (0)