Skip to content

Commit 5998f88

Browse files
tannergoodingericstjjeffhandley
authored
Mark the new tensor APIs as experimental for .NET 9 (#105268)
* Mark the new tensor APIs as experimental for .NET 9 * Apply SNTEXP0001 to other internal API * Suppress SNTEXP0001 in System.Numerics.Tensors.Tests * Use SYSLIB5001. Central registration of experimental API diagnostic ids. * Add Experimentals.cs (missed in prior commit) * Revert SLN changes. Add UrlFormat property to attributes where missing. * Ensure the net8 tensors tests also don't warn for the experimental API usage --------- Co-authored-by: Eric StJohn <[email protected]> Co-authored-by: Jeff Handley <[email protected]>
1 parent cbfd8ec commit 5998f88

19 files changed

+80
-2
lines changed

docs/project/list-of-diagnostics.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,20 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
276276
| __`SYSLIBSUPPRESS0001`__ | CA1822 | Do not offer to make methods static when the methods need to be instance methods for a custom marshaller shape. |
277277
| __`SYSLIBSUPPRESS0002`__ | IL2026 | ConfigurationBindingGenerator: suppress RequiresUnreferencedCode diagnostic for binding call that has been intercepted by a generated static variant. |
278278
| __`SYSLIBSUPPRESS0003`__ | IL3050 | ConfigurationBindingGenerator: suppress RequiresDynamicCode diagnostic for binding call that has been intercepted by a generated static variant. |
279+
280+
## Experimental APIs
281+
282+
APIs can be marked as `[Experimental]` if their shape or functionality is included in a release but not yet officially supported. Experimental APIs offer the opportunity to collect customer feedback on these APIs in a major release, usually refining the APIs and removing the `[Experimental]` attribute in the next release. The `[Experimental]` attribute differs from `[RequiresPreviewFeatures]`, wherein:
283+
284+
* `[RequiresPreviewFeatures]` APIs require a corresponding preview feature in another product area such as the compiler or SDK
285+
* `[Experimental]` APIs are entirely self-contained within the libraries and do not require preview features in other parts of the product
286+
287+
The diagnostic id values reserved for experimental APIs are `SYSLIB5001` through `SYSLIB5999`. When marking an API as `[Experimental]`, claim the next three-digit identifier in the `SYSLIB5###` sequence and add it to the list below. The URL template for all experimental APIs is `https://aka.ms/dotnet-warnings/{0}`. The `{0}` placeholder is replaced by the compiler with the `SYSLIB5###` identifier.
288+
289+
### Experimental Diagnostics (`SYSLIB5001` - `SYSLIB5999`)
290+
291+
Diagnostic id values for experimental APIs must not be recycled, as that could silently opt customers into new experimental APIs where they had previously suppressed the ID for a previous usage of the value.
292+
293+
| Diagnostic ID | Introduced | Removed | Description |
294+
| :---------------- | ---------: | ------: | :---------- |
295+
| __`SYSLIB5001`__ | .NET 9 | TBD | `Tensor<T>` and related APIs in System.Numerics.Tensors are experimental in .NET 9 |
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace System
5+
{
6+
internal static class Experimentals
7+
{
8+
internal const string SharedUrlFormat = "https://aka.ms/dotnet-warnings/{0}";
9+
10+
// Please see docs\project\list-of-diagnostics.md for instructions on the steps required
11+
// to introduce an experimental API, claim a diagnostic id, and ensure the
12+
// "aka.ms/dotnet-warnings/{0}" URL points to documentation for the API.
13+
// The diagnostic IDs reserved for experimental APIs are SYSLIB5### (SYSLIB5001 - SYSLIB5999).
14+
15+
// When an API is no longer marked as experimental, the diagnostic ID should be removed from this file
16+
// but retained in the table in docs\project\list-of-diagnostics.md to prevent reuse. Be sure to remove
17+
// suppressions from the codebase as well.
18+
19+
// Tensor<T> and related APIs are marked as [Experimental] in .NET 9
20+
internal const string TensorTDiagId = "SYSLIB5001";
21+
22+
// When adding a new diagnostic ID, add it to the table in docs\project\list-of-diagnostics.md as well.
23+
// Keep new const identifiers above this comment.
24+
}
25+
}

src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace System.Buffers
88
{
9+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
910
public readonly partial struct NIndex : System.IEquatable<System.Buffers.NIndex>
1011
{
1112
private readonly int _dummyPrimitive;
@@ -29,6 +30,7 @@ namespace System.Buffers
2930
public System.Index ToIndexUnchecked() { throw null; }
3031
public override string ToString() { throw null; }
3132
}
33+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
3234
public readonly partial struct NRange : System.IEquatable<System.Buffers.NRange>
3335
{
3436
private readonly int _dummyPrimitive;
@@ -53,6 +55,7 @@ namespace System.Buffers
5355
}
5456
namespace System.Numerics.Tensors
5557
{
58+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
5659
public partial interface IReadOnlyTensor<TSelf, T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable where TSelf : System.Numerics.Tensors.IReadOnlyTensor<TSelf, T>
5760
{
5861
static abstract TSelf? Empty { get; }
@@ -80,6 +83,7 @@ public partial interface IReadOnlyTensor<TSelf, T> : System.Collections.Generic.
8083
bool TryCopyTo(scoped System.Numerics.Tensors.TensorSpan<T> destination);
8184
bool TryFlattenTo(scoped System.Span<T> destination);
8285
}
86+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
8387
public partial interface ITensor<TSelf, T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor<TSelf, T> where TSelf : System.Numerics.Tensors.ITensor<TSelf, T>
8488
{
8589
bool IsReadOnly { get; }
@@ -98,6 +102,7 @@ public partial interface ITensor<TSelf, T> : System.Collections.Generic.IEnumera
98102
void Fill(T value);
99103
new ref T GetPinnableReference();
100104
}
105+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
101106
public readonly ref partial struct ReadOnlyTensorSpan<T>
102107
{
103108
private readonly object _dummy;
@@ -157,6 +162,7 @@ public ref partial struct Enumerator
157162
public bool MoveNext() { throw null; }
158163
}
159164
}
165+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
160166
public static partial class Tensor
161167
{
162168
public static System.Numerics.Tensors.Tensor<T> Abs<T>(in System.Numerics.Tensors.ReadOnlyTensorSpan<T> x) where T : System.Numerics.INumberBase<T> { throw null; }
@@ -674,6 +680,7 @@ public static void Truncate<T>(System.ReadOnlySpan<T> x, System.Span<T> destinat
674680
public static void Xor<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, System.Span<T> destination) where T : System.Numerics.IBitwiseOperators<T, T, T> { }
675681
public static void Xor<T>(System.ReadOnlySpan<T> x, T y, System.Span<T> destination) where T : System.Numerics.IBitwiseOperators<T, T, T> { }
676682
}
683+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
677684
public readonly ref partial struct TensorSpan<T>
678685
{
679686
private readonly object _dummy;
@@ -735,6 +742,7 @@ public ref partial struct Enumerator
735742
public bool MoveNext() { throw null; }
736743
}
737744
}
745+
[System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
738746
public sealed partial class Tensor<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.Tensor<T>, T>, System.Numerics.Tensors.ITensor<System.Numerics.Tensors.Tensor<T>, T>
739747
{
740748
internal Tensor() { }

src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
<PackageDescription>Provides support for operating over tensors.</PackageDescription>
88
<GenAPIExcludeApiList>ReferenceAssemblyExclusions.txt</GenAPIExcludeApiList>
99
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
10+
<!-- SYSLIB5001: Tensor<T> and related APIs are Experimental in .NET 9 -->
11+
<NoWarn>$(NoWarn);SYSLIB5001</NoWarn>
1012
</PropertyGroup>
1113

1214
<ItemGroup>
1315
<Compile Include="System\Numerics\Tensors\TensorPrimitives.Single.cs" />
1416
<Compile Include="System\Numerics\Tensors\TensorPrimitives.Helpers.cs" />
1517
<Compile Include="System\ThrowHelper.cs" />
18+
<Compile Include="$(CommonPath)System\Experimentals.cs" Link="Common\System\Experimentals.cs" />
1619
</ItemGroup>
1720

1821
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">

src/libraries/System.Numerics.Tensors/src/System/NIndex.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace System.Buffers
1414
/// int lastElement = someArray[^1]; // lastElement = 5
1515
/// </code>
1616
/// </remarks>
17+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
1718
public readonly struct NIndex : IEquatable<NIndex>
1819
{
1920
private readonly nint _value;

src/libraries/System.Numerics.Tensors/src/System/NRange.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace System.Buffers
1515
/// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 }
1616
/// </code>
1717
/// </remarks>
18+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
1819
public readonly struct NRange : IEquatable<NRange>
1920
{
2021
/// <summary>Represent the inclusive start NIndex of the NRange.</summary>

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace System.Numerics.Tensors
99
{
10+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
1011
public interface IReadOnlyTensor<TSelf, T> : IEnumerable<T>
1112
where TSelf : IReadOnlyTensor<TSelf, T>
1213
{

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Buffers;
5+
using System.Diagnostics.CodeAnalysis;
56

67
namespace System.Numerics.Tensors
78
{
9+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
810
public interface ITensor<TSelf, T>
911
: IReadOnlyTensor<TSelf, T>
1012
where TSelf : ITensor<TSelf, T>

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace System.Numerics.Tensors
2121
/// </summary>
2222
[DebuggerTypeProxy(typeof(TensorSpanDebugView<>))]
2323
[DebuggerDisplay("{ToString(),raw}")]
24+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
2425
public readonly ref struct ReadOnlyTensorSpan<T>
2526
{
2627
/// <summary>A byref or a native ptr.</summary>

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Collections.Generic;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.Linq;
67
using System.Runtime.InteropServices;
78
using Microsoft.VisualBasic;

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections;
66
using System.Collections.Generic;
77
using System.ComponentModel;
8+
using System.Diagnostics.CodeAnalysis;
89
using System.Linq;
910
using System.Reflection.Metadata.Ecma335;
1011
using System.Runtime.CompilerServices;
@@ -17,6 +18,7 @@
1718

1819
namespace System.Numerics.Tensors
1920
{
21+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
2022
public sealed class Tensor<T>
2123
: ITensor<Tensor<T>, T>
2224
{

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
using static System.Runtime.InteropServices.JavaScript.JSType;
1212
using System.Security.Cryptography;
1313
using System.Runtime.Serialization;
14+
using System.Diagnostics.CodeAnalysis;
1415

1516
#pragma warning disable CS8601 // Possible null reference assignment.
1617
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
1718

1819
namespace System.Numerics.Tensors
1920
{
21+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
2022
public static partial class Tensor
2123
{
2224
#region AsReadOnlySpan

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorHelpers.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.Linq;
67
using System.Runtime.InteropServices;
78

89
namespace System.Numerics.Tensors
910
{
11+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
1012
internal static class TensorHelpers
1113
{
1214

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace System.Numerics.Tensors
1010
{
11+
12+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
1113
internal readonly struct TensorShape
1214
{
1315
// Used to determine when we need to allocate a metadata array

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace System.Numerics.Tensors
2121
/// </summary>
2222
[DebuggerTypeProxy(typeof(TensorSpanDebugView<>))]
2323
[DebuggerDisplay("{ToString(),raw}")]
24+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
2425
public readonly ref struct TensorSpan<T>
2526
{
2627
/// <summary>A byref or a native ptr.</summary>

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5+
using System.Diagnostics.CodeAnalysis;
56

67
namespace System.Numerics.Tensors
78
{
9+
10+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
811
internal sealed class TensorSpanDebugView<T>
912
{
1013
private readonly T[] _array;

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanHelpers.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
using System.Buffers;
55
using System.Collections.Specialized;
66
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Linq;
89
using System.Reflection;
910
using System.Runtime.CompilerServices;
1011

1112
namespace System.Numerics.Tensors
1213
{
14+
15+
[Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
1316
internal static partial class TensorSpanHelpers
1417
{
1518
internal static bool AreShapesTheSame<T>(ReadOnlyTensorSpan<T> tensor1, ReadOnlyTensorSpan<T> tensor2)

src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
-->
77

88
<Project Sdk="Microsoft.NET.Sdk">
9-
9+
1010
<PropertyGroup>
1111
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
1212
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1313
<DefineConstants>$(DefineConstants);SNT_NET8_TESTS</DefineConstants>
14+
<NoWarn>$(NoWarn);SYSLIB5001</NoWarn>
1415
</PropertyGroup>
1516

1617
<ItemGroup>
@@ -21,7 +22,7 @@
2122
<Compile Include="..\TensorPrimitives.ConvertTo.cs" />
2223
<Compile Include="..\TensorPrimitives.Generic.cs" />
2324
</ItemGroup>
24-
25+
2526
<ItemGroup>
2627
<ProjectReference Include="..\..\src\System.Numerics.Tensors.csproj" SkipUseReferenceAssembly="true">
2728
<SetTargetFramework>TargetFramework=net8.0</SetTargetFramework>

src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<PropertyGroup>
44
<TargetFrameworks>$(NetCoreAppCurrent);$(NetFrameworkMinimum)</TargetFrameworks>
55
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
6+
<!-- SYSLIB5001: Tensor<T> and related APIs are Experimental in .NET 9 -->
7+
<NoWarn>$(NoWarn);SYSLIB5001</NoWarn>
68
</PropertyGroup>
79

810
<PropertyGroup>

0 commit comments

Comments
 (0)