Make System.Runtime.CompilerServices.Unsafe inbox (dotnet/corefx#35526)
authorEric StJohn <ericstj@microsoft.com>
Sat, 23 Feb 2019 02:20:16 +0000 (18:20 -0800)
committerJan Kotas <jkotas@microsoft.com>
Sat, 23 Feb 2019 02:20:16 +0000 (18:20 -0800)
* Make System.Runtime.CompilerServices.Unsafe inbox

Fix a couple places where we wanted to use it from other inbox assemblies but couldn't.

Unsafe remains as a package and newer versions of Unsafe will replace the inbox Version,
permitting us to add API over time.

* Update Rune tests to use TryEncodeToUtf8Bytes directly

* Add temporary suppression to package tests

Commit migrated from https://github.com/dotnet/corefx/commit/9074d9f5b513a95b7eac9ba1112069c29230d1d2

src/libraries/System.Runtime.CompilerServices.Unsafe/Directory.Build.props
src/libraries/System.Runtime.CompilerServices.Unsafe/pkg/System.Runtime.CompilerServices.Unsafe.pkgproj
src/libraries/System.Runtime.Serialization.Formatters/src/System.Runtime.Serialization.Formatters.csproj
src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryFormatterWriter.cs
src/libraries/System.Runtime/ref/System.Runtime.cs
src/libraries/System.Runtime/tests/System/Text/RuneTests.netcoreapp.cs
src/libraries/System.Text.Json/src/System.Text.Json.csproj
src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs
src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs
src/libraries/pkg/Microsoft.Private.PackageBaseline/packageIndex.json
src/libraries/pkg/test/frameworkSettings/netcoreapp3.0/settings.targets

index b14d2b415e1f9009b8993fa295fefe79d648f2d9..b06ba557398f73d30ef29f238fe8361d20eaa9bb 100644 (file)
@@ -4,6 +4,7 @@
   <PropertyGroup>
     <AssemblyVersion>4.0.5.0</AssemblyVersion>
     <StrongNameKeyId>Microsoft</StrongNameKeyId>
+    <IsNETCoreApp>true</IsNETCoreApp>
     <IsUAP>true</IsUAP>
   </PropertyGroup>
 </Project>
index ec99d138f62cee923f53705bac2d593a7c6a7f01..096fcad6be48cb089f1fbfc9df538581d818fd75 100644 (file)
     <!-- this package is part of the implementation closure of NETStandard.Library
          therefore it cannot reference NETStandard.Library -->
     <SuppressMetaPackage Include="NETStandard.Library" />
-    <InboxOnTargetFramework Include="uap10.0.16300" />
+
+    <!-- Since UAP and .NETCoreApp are package based we still want to enable
+         OOBing libraries that happen to overlap with their framework package.
+         This avoids us having to lock the API in our NuGet packages just 
+         to match what shipped inbox: since we can provide a new library 
+         we can update it to add API without raising the netstandard version. -->
+    <ValidatePackageSuppression Include="TreatAsOutOfBox">
+      <Value>.NETCoreApp;UAP</Value>
+    </ValidatePackageSuppression>
   </ItemGroup>
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" />
 </Project>
\ No newline at end of file
index 791901fee44a9415acb8982348a255fc29816619..a27d2690bc27f3763c8cc321d7127c81dd04a72e 100644 (file)
@@ -67,6 +67,7 @@
     <Reference Include="System.Memory" />
     <Reference Include="System.Resources.ResourceManager" />
     <Reference Include="System.Runtime" />
+    <Reference Include="System.Runtime.CompilerServices.Unsafe" />
     <Reference Include="System.Runtime.Extensions" />
     <Reference Include="System.Text.Encoding.Extensions" />
     <Reference Include="System.Threading" />
index 90fc86d0803168a64aa9dbf46e9f276717cb3a4f..28e5d3b2931d114cd579ad0b9e29e521394e3025 100644 (file)
@@ -6,6 +6,7 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Text;
 
@@ -86,10 +87,8 @@ namespace System.Runtime.Serialization.Formatters.Binary
             // which just returns the value of its sole Int64 dateData field.  Here, we don't
             // have access to that member (which doesn't even exist anymore, since it was only for
             // BinaryFormatter, which is now in a separate assembly).  To address that,
-            // we access the sole field directly via an unsafe cast; ideally this would
-            // just use Unsafe.As, but since we can't use that here due to not having a netcoreapp
-            // build of System.Runtime.CompilerServices.Unsafe.dll, we instead go through span.
-            long dateData = MemoryMarshal.Cast<DateTime, long>(MemoryMarshal.CreateReadOnlySpan(ref value, 1))[0];
+            // we access the sole field directly via an unsafe cast.
+            long dateData = Unsafe.As<DateTime, long>(ref value);
             WriteInt64(dateData);
         }
 
index 94a89b9cbb878b5052fd40d772b5b78d0b728730..fb5baba64cb8dbbdb1bb90fa9a256478d191bd2e 100644 (file)
@@ -7709,6 +7709,7 @@ namespace System.Text
         [CLSCompliant(false)]
         public static bool TryCreate(uint value, out Rune result) { throw null; }
         public bool TryEncode(Span<char> destination, out int charsWritten) { throw null; }
+        public bool TryEncodeToUtf8Bytes(Span<byte> destination, out int bytesWritten) { throw null; }
         public static bool TryGetRuneAt(string input, int index, out Rune value) { throw null; }
         public static double GetNumericValue(Rune value) { throw null; }
         public static System.Globalization.UnicodeCategory GetUnicodeCategory(Rune value) { throw null; }
index 73767aa76c0446c38d04086d9ab7852af96fe690..81b41675ec4dd94838961b79f3501ce40f4725e2 100644 (file)
@@ -454,14 +454,14 @@ namespace System.Text.Tests
             // First, try with a buffer that's too short
 
             Span<byte> utf8Buffer = stackalloc byte[rune.Utf8SequenceLength - 1];
-            bool success = TryEncodeToUtf8Bytes_Fn(ref rune, utf8Buffer, out int bytesWritten);
+            bool success = rune.TryEncodeToUtf8Bytes(utf8Buffer, out int bytesWritten);
             Assert.False(success);
             Assert.Equal(0, bytesWritten);
 
             // Then, try with a buffer that's appropriately sized
 
             utf8Buffer = stackalloc byte[rune.Utf8SequenceLength];
-            success = TryEncodeToUtf8Bytes_Fn(ref rune, utf8Buffer, out bytesWritten);
+            success = rune.TryEncodeToUtf8Bytes(utf8Buffer, out bytesWritten);
             Assert.True(success);
             Assert.Equal(testData.Utf8Sequence.Length, bytesWritten);
             Assert.True(utf8Buffer.SequenceEqual(testData.Utf8Sequence));
@@ -469,19 +469,10 @@ namespace System.Text.Tests
             // Finally, try with a buffer that's too long (should succeed)
 
             utf8Buffer = stackalloc byte[rune.Utf8SequenceLength + 1];
-            success = TryEncodeToUtf8Bytes_Fn(ref rune, utf8Buffer, out bytesWritten);
+            success = rune.TryEncodeToUtf8Bytes(utf8Buffer, out bytesWritten);
             Assert.True(success);
             Assert.Equal(testData.Utf8Sequence.Length, bytesWritten);
             Assert.True(utf8Buffer.Slice(0, testData.Utf8Sequence.Length).SequenceEqual(testData.Utf8Sequence));
         }
-
-        private delegate bool TryEncodeToUtf8Bytes_Del(ref Rune rune, Span<byte> destination, out int bytesWritten);
-        private static readonly TryEncodeToUtf8Bytes_Del TryEncodeToUtf8Bytes_Fn = CreateTryEncodeToUtf8BytesDelegate();
-
-        private static TryEncodeToUtf8Bytes_Del CreateTryEncodeToUtf8BytesDelegate()
-        {
-            var methodInfo = typeof(Rune).GetMethod("TryEncodeToUtf8Bytes", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-            return (TryEncodeToUtf8Bytes_Del)methodInfo.CreateDelegate(typeof(TryEncodeToUtf8Bytes_Del));
-        }
     }
 }
index fa73ef91c07774b10a4a3992d2621d78620e13a6..ec0e780b1ef007d9618fa1a2c8bc491fa30b516a 100644 (file)
@@ -8,7 +8,7 @@
     <!-- For the inbox library (that is shipping with the product), this should always be true. -->
     <!-- BUILDING_INBOX_LIBRARY is only false when building for netstandard to validate that the sources are netstandard compatible. -->
     <!-- This is meant to help with producing a source package and not to ship a netstandard compatible binary. -->
-    <DefineConstants Condition="'$(TargetGroup)' != 'netstandard'">$(DefineConstants);BUILDING_INBOX_LIBRARY</DefineConstants>
+    <DefineConstants Condition="'$(TargetsNETStandard)' != 'true'">$(DefineConstants);BUILDING_INBOX_LIBRARY</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="System\Text\Json\BitStack.cs" />
     <Compile Include="System\Text\Json\Writer\Utf8JsonWriter.WriteValues.String.cs" />
     <Compile Include="System\Text\Json\Writer\Utf8JsonWriter.WriteValues.UnsignedNumber.cs" />
   </ItemGroup>
-  <ItemGroup Condition="'$(TargetGroup)' != 'netstandard'">
-    <ProjectReference Include="..\..\System.Memory\src\System.Memory.csproj" />
-    <ProjectReference Include="..\..\System.Runtime.Extensions\src\System.Runtime.Extensions.csproj" />
+  <ItemGroup Condition="'$(TargetsNETStandard)' != 'true'">
+    <Reference Include="System.Diagnostics.Debug" />
+    <Reference Include="System.Resources.ResourceManager" />
+    <Reference Include="System.Runtime" />
+    <Reference Include="System.Runtime.Extensions" />
+    <Reference Include="System.Text.Encoding.Extensions" />
+    <Reference Include="System.Threading.Tasks" />
   </ItemGroup>
-  <ItemGroup Condition="'$(TargetGroup)' != 'netstandard'">
-    <ReferenceFromRuntime Include="System.Private.CoreLib" />
-  </ItemGroup>
-  <ItemGroup Condition="'$(TargetGroup)' == 'netstandard'">
+  <ItemGroup>
     <Reference Include="System.Buffers" />
     <Reference Include="System.Memory" />
     <Reference Include="System.Numerics.Vectors" />
index e24adda9ac5c8a1662fe3b34f1b6f2008c9c0549..7c927451a84131106b200548703d059a923206fe 100644 (file)
@@ -6,11 +6,7 @@ using System.Buffers;
 using System.Buffers.Text;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
-#if BUILDING_INBOX_LIBRARY
-using Internal.Runtime.CompilerServices;
-#else
 using System.Runtime.CompilerServices;
-#endif
 
 namespace System.Text.Json
 {
index 96727cee1368bd0acb121e9a3080c4c13b3d72e1..1620655c928fea3588194ca0fae40aedcfffd7aa 100644 (file)
@@ -7,10 +7,6 @@ using System.Numerics;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
-#if BUILDING_INBOX_LIBRARY
-using Internal.Runtime.CompilerServices;
-#endif
-
 namespace System.Text.Json
 {
     internal static partial class JsonReaderHelper
index dadf189767a4d296d16673da9087f7df9b3ec298..0f193a2b57ef063da2c18c67ef36251d0fc3d9e5 100644 (file)
       ],
       "BaselineVersion": "4.5.1",
       "InboxOn": {
-        "uap10.0.16300": "4.0.5.0"
+        "uap10.0.16300": "4.0.5.0",
+        "netcoreapp3.0": "4.0.5.0"
       },
       "AssemblyVersionInPackageVersion": {
         "4.0.3.0": "4.4.0",
index a5193eaa48697e6db38f7ae00033e142bf0a9d96..c201b38104d6cb5f5367109d5165cb61738fc650 100644 (file)
@@ -6,4 +6,12 @@
     <!-- use the most recent MS.NETCore.App we have from upstack -->
     <RuntimeFrameworkVersion>$(MicrosoftNETCoreAppPackageVersion)</RuntimeFrameworkVersion>
   </PropertyGroup>
+  <ItemGroup>
+    <!-- unsafe is part of the framework but we don't yet have a MicrosoftNETCoreAppPackageVersion with that change -->
+    <IgnoredReference Include="System.Runtime.CompilerServices.Unsafe"/>
+  </ItemGroup>
+  <Target Name="CheckForWorkaroundRemoval" AfterTargets="ResolveReferences">
+    <Error Condition="'%(Reference.FileName)' == 'System.Runtime.CompilerServices.Unsafe' AND '%(Reference.NuGetPackageId)' == 'Microsoft.NETCore.App'"
+           Text="Please remove IgnoredReference workaround from pkg\test\frameworkSettings\netcoreapp3.0\settings.targets" />
+  </Target>
 </Project>