Document span lifetime issue in CreateSpan (dotnet/corefx#30490) (#18528)
authordotnet bot <dotnet-bot@dotnetfoundation.org>
Mon, 18 Jun 2018 17:45:42 +0000 (10:45 -0700)
committerJan Kotas <jkotas@microsoft.com>
Mon, 18 Jun 2018 17:45:42 +0000 (10:45 -0700)
The language rules around span safety that C# and F# adhere to assume
there is no way to create a `Span<T>` wrapper over a `ref` local /
parameter. This means `ref` inputs into a method are not considered when
calculating the allowed lifetime of a returned `Span<T>`. Hence both
CreateSpan and CreateReadOnlySpan will be assumed to have heap lifetime
even when provided stack based inputs. Example:

``` c#
Span<int> Example() {
  int i = 42;
  Span<int> span = MemoryMarshal.CreateSpan(ref i, length: 1);
  return span; // C# and F# will allow this
}
```

In this case the actual lifetime of `span` is that of `i`. Yet the
compiler doesn't consider the `ref i` input and hence believes this must
be heap based and hence safe to return out of the method.

This is okay as these methods are unsafe. But want to explicitly
document that fact.

More information on the safety rules can be found in the [span safety
proposal](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/span-safety.md)

Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
src/System.Private.CoreLib/shared/System/Runtime/InteropServices/MemoryMarshal.Fast.cs

index e212f7d4b0bca6f0a45d0995a6438cb35b706f74..c71c7820ef45c7957a31469dc134d9b6bb8f8c6e 100644 (file)
@@ -214,6 +214,7 @@ namespace System.Runtime.InteropServices
         /// </summary>
         /// <param name="reference">A reference to data.</param>
         /// <param name="length">The number of <typeparamref name="T"/> elements the memory contains.</param>
+        /// <returns>The lifetime of the returned span will not be validated for safety by span-aware languages.</returns>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static Span<T> CreateSpan<T>(ref T reference, int length) => new Span<T>(ref reference, length);
 
@@ -224,6 +225,7 @@ namespace System.Runtime.InteropServices
         /// </summary>
         /// <param name="reference">A reference to data.</param>
         /// <param name="length">The number of <typeparamref name="T"/> elements the memory contains.</param>
+        /// <returns>The lifetime of the returned span will not be validated for safety by span-aware languages.</returns>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static ReadOnlySpan<T> CreateReadOnlySpan<T>(ref T reference, int length) => new ReadOnlySpan<T>(ref reference, length);
     }