diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index c8295e99c70b6..6f3c52063df44 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -276,3 +276,20 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL | __`SYSLIBSUPPRESS0001`__ | CA1822 | Do not offer to make methods static when the methods need to be instance methods for a custom marshaller shape. | | __`SYSLIBSUPPRESS0002`__ | IL2026 | ConfigurationBindingGenerator: suppress RequiresUnreferencedCode diagnostic for binding call that has been intercepted by a generated static variant. | | __`SYSLIBSUPPRESS0003`__ | IL3050 | ConfigurationBindingGenerator: suppress RequiresDynamicCode diagnostic for binding call that has been intercepted by a generated static variant. | + +## Experimental APIs + +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: + +* `[RequiresPreviewFeatures]` APIs require a corresponding preview feature in another product area such as the compiler or SDK +* `[Experimental]` APIs are entirely self-contained within the libraries and do not require preview features in other parts of the product + +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. + +### Experimental Diagnostics (`SYSLIB5001` - `SYSLIB5999`) + +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. + +| Diagnostic ID | Introduced | Removed | Description | +| :---------------- | ---------: | ------: | :---------- | +| __`SYSLIB5001`__ | .NET 9 | TBD | `Tensor` and related APIs in System.Numerics.Tensors are experimental in .NET 9 | diff --git a/src/libraries/Common/src/System/Experimentals.cs b/src/libraries/Common/src/System/Experimentals.cs new file mode 100644 index 0000000000000..befcdca48327d --- /dev/null +++ b/src/libraries/Common/src/System/Experimentals.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System +{ + internal static class Experimentals + { + internal const string SharedUrlFormat = "https://aka.ms/dotnet-warnings/{0}"; + + // Please see docs\project\list-of-diagnostics.md for instructions on the steps required + // to introduce an experimental API, claim a diagnostic id, and ensure the + // "aka.ms/dotnet-warnings/{0}" URL points to documentation for the API. + // The diagnostic IDs reserved for experimental APIs are SYSLIB5### (SYSLIB5001 - SYSLIB5999). + + // When an API is no longer marked as experimental, the diagnostic ID should be removed from this file + // but retained in the table in docs\project\list-of-diagnostics.md to prevent reuse. Be sure to remove + // suppressions from the codebase as well. + + // Tensor and related APIs are marked as [Experimental] in .NET 9 + internal const string TensorTDiagId = "SYSLIB5001"; + + // When adding a new diagnostic ID, add it to the table in docs\project\list-of-diagnostics.md as well. + // Keep new const identifiers above this comment. + } +} diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs index 820b2ea99058f..9a4b08633db1d 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs @@ -6,6 +6,7 @@ namespace System.Buffers { + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public readonly partial struct NIndex : System.IEquatable { private readonly int _dummyPrimitive; @@ -29,6 +30,7 @@ namespace System.Buffers public System.Index ToIndexUnchecked() { throw null; } public override string ToString() { throw null; } } + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public readonly partial struct NRange : System.IEquatable { private readonly int _dummyPrimitive; @@ -53,6 +55,7 @@ namespace System.Buffers } namespace System.Numerics.Tensors { + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public partial interface IReadOnlyTensor : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable where TSelf : System.Numerics.Tensors.IReadOnlyTensor { static abstract TSelf? Empty { get; } @@ -80,6 +83,7 @@ public partial interface IReadOnlyTensor : System.Collections.Generic. bool TryCopyTo(scoped System.Numerics.Tensors.TensorSpan destination); bool TryFlattenTo(scoped System.Span destination); } + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public partial interface ITensor : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor where TSelf : System.Numerics.Tensors.ITensor { bool IsReadOnly { get; } @@ -98,6 +102,7 @@ public partial interface ITensor : System.Collections.Generic.IEnumera void Fill(T value); new ref T GetPinnableReference(); } + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public readonly ref partial struct ReadOnlyTensorSpan { private readonly object _dummy; @@ -157,6 +162,7 @@ public ref partial struct Enumerator public bool MoveNext() { throw null; } } } + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public static partial class Tensor { public static System.Numerics.Tensors.Tensor Abs(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.INumberBase { throw null; } @@ -674,6 +680,7 @@ public static void Truncate(System.ReadOnlySpan x, System.Span destinat public static void Xor(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) where T : System.Numerics.IBitwiseOperators { } public static void Xor(System.ReadOnlySpan x, T y, System.Span destination) where T : System.Numerics.IBitwiseOperators { } } + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public readonly ref partial struct TensorSpan { private readonly object _dummy; @@ -735,6 +742,7 @@ public ref partial struct Enumerator public bool MoveNext() { throw null; } } } + [System.Diagnostics.CodeAnalysis.Experimental("SYSLIB5001", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public sealed partial class Tensor : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor, T>, System.Numerics.Tensors.ITensor, T> { internal Tensor() { } diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index b653420933405..9b4b736bd0689 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -7,12 +7,15 @@ Provides support for operating over tensors. ReferenceAssemblyExclusions.txt true + + $(NoWarn);SYSLIB5001 + diff --git a/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs b/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs index 512d1ecb7ac5b..0ccfebea718b7 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs @@ -14,6 +14,7 @@ namespace System.Buffers /// int lastElement = someArray[^1]; // lastElement = 5 /// /// + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly struct NIndex : IEquatable { private readonly nint _value; diff --git a/src/libraries/System.Numerics.Tensors/src/System/NRange.cs b/src/libraries/System.Numerics.Tensors/src/System/NRange.cs index 974407fae1679..5335da4488e1f 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/NRange.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/NRange.cs @@ -15,6 +15,7 @@ namespace System.Buffers /// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } /// /// + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly struct NRange : IEquatable { /// Represent the inclusive start NIndex of the NRange. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs index e9072f160bb60..de5611c765edc 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs @@ -7,6 +7,7 @@ namespace System.Numerics.Tensors { + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public interface IReadOnlyTensor : IEnumerable where TSelf : IReadOnlyTensor { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs index b88169543aa6f..83abcc1def2fb 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; +using System.Diagnostics.CodeAnalysis; namespace System.Numerics.Tensors { + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public interface ITensor : IReadOnlyTensor where TSelf : ITensor diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs index 7fd72d6e47a6c..5122ca3e8513a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs @@ -21,6 +21,7 @@ namespace System.Numerics.Tensors /// [DebuggerTypeProxy(typeof(TensorSpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly ref struct ReadOnlyTensorSpan { /// A byref or a native ptr. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs index dea1d54b0a3ba..5c9d78558cd71 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.InteropServices; using Microsoft.VisualBasic; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs index 92030f4877d4c..48d87aa7ca6da 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection.Metadata.Ecma335; using System.Runtime.CompilerServices; @@ -17,6 +18,7 @@ namespace System.Numerics.Tensors { + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public sealed class Tensor : ITensor, T> { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs index 506655fd13234..904bf14c63437 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs @@ -11,12 +11,14 @@ using static System.Runtime.InteropServices.JavaScript.JSType; using System.Security.Cryptography; using System.Runtime.Serialization; +using System.Diagnostics.CodeAnalysis; #pragma warning disable CS8601 // Possible null reference assignment. #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. namespace System.Numerics.Tensors { + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static partial class Tensor { #region AsReadOnlySpan diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorHelpers.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorHelpers.cs index 76e541a25be1c..163075ce5c13d 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorHelpers.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorHelpers.cs @@ -2,11 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.InteropServices; namespace System.Numerics.Tensors { + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] internal static class TensorHelpers { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs index f3b4380cc3f29..5aa155efff6a4 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs @@ -8,6 +8,8 @@ namespace System.Numerics.Tensors { + + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] internal readonly struct TensorShape { // Used to determine when we need to allocate a metadata array diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs index 66a7940256fc6..c2d12bd7e814c 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs @@ -21,6 +21,7 @@ namespace System.Numerics.Tensors /// [DebuggerTypeProxy(typeof(TensorSpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly ref struct TensorSpan { /// A byref or a native ptr. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs index ab6073a52341a..4b694d7d72f57 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs @@ -2,9 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Numerics.Tensors { + + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] internal sealed class TensorSpanDebugView { private readonly T[] _array; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanHelpers.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanHelpers.cs index 313f4556e5add..d84b1130c96c3 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanHelpers.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanHelpers.cs @@ -4,12 +4,15 @@ using System.Buffers; using System.Collections.Specialized; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; namespace System.Numerics.Tensors { + + [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] internal static partial class TensorSpanHelpers { internal static bool AreShapesTheSame(ReadOnlyTensorSpan tensor1, ReadOnlyTensorSpan tensor2) diff --git a/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj index 1f8f82a11dc84..1240240ca52b8 100644 --- a/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj @@ -6,11 +6,12 @@ --> - + $(NetCoreAppCurrent) true $(DefineConstants);SNT_NET8_TESTS + $(NoWarn);SYSLIB5001 @@ -21,7 +22,7 @@ - + TargetFramework=net8.0 diff --git a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj index 136e487d70d0a..cce46f3a5eb64 100644 --- a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj @@ -3,6 +3,8 @@ $(NetCoreAppCurrent);$(NetFrameworkMinimum) true + + $(NoWarn);SYSLIB5001