[dawn][native] Use HeapArray::MoveToSpan to return array data to the API

Also changes HeapArrayFrom to not use Uninit so that it can be used with
values that are not trivially constructible.

Bug: 439062058
Change-Id: I0acaeb3ee6f5d6d109704117bcb553182c63e6de
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/323717
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/native/Features.cpp b/src/dawn/native/Features.cpp
index 7cc3299..41596f7 100644
--- a/src/dawn/native/Features.cpp
+++ b/src/dawn/native/Features.cpp
@@ -33,6 +33,7 @@
 #include "src/dawn/common/ityp_array.h"
 #include "src/utils/assert.h"
 #include "src/utils/compiler.h"
+#include "src/utils/heap_array.h"
 
 namespace dawn::native {
 namespace {
@@ -515,14 +516,14 @@
     }
 
     // This will be freed by wgpuSupportedFeaturesFreeMembers.
-    wgpu::FeatureName* features = new wgpu::FeatureName[count];
+    auto features = HeapArray<wgpu::FeatureName>(count);
     uint32_t index = 0;
     for (Feature f : featuresBitSet) {
-        DAWN_UNSAFE_TODO(features[index++]) = ToAPI(f);
+        features[index++] = ToAPI(f);
     }
     DAWN_ASSERT(index == count);
-    // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-    supportedFeatures->features = DAWN_UNSAFE_TODO({features, count});
+
+    supportedFeatures->features = std::move(features).MoveToSpan();
 }
 
 }  // namespace dawn::native
diff --git a/src/dawn/native/Instance.cpp b/src/dawn/native/Instance.cpp
index 3cc2848..a834dab 100644
--- a/src/dawn/native/Instance.cpp
+++ b/src/dawn/native/Instance.cpp
@@ -45,6 +45,7 @@
 #include "src/dawn/native/Toggles.h"
 #include "src/utils/assert.h"
 #include "src/utils/compiler.h"
+#include "src/utils/heap_array.h"
 #include "src/utils/log.h"
 
 // For SwiftShader fallback
@@ -795,16 +796,7 @@
 void InstanceBase::APIGetWGSLLanguageFeatures(SupportedWGSLLanguageFeatures* features) const {
     DAWN_ASSERT(features != nullptr);
 
-    size_t featureCount = mWGSLFeatures.size();
-    wgpu::WGSLLanguageFeatureName* wgslFeatures = new wgpu::WGSLLanguageFeatureName[featureCount];
-    uint32_t index = 0;
-    for (wgpu::WGSLLanguageFeatureName feature : mWGSLFeatures) {
-        DAWN_UNSAFE_TODO(wgslFeatures[index++]) = feature;
-    }
-    DAWN_CHECK(index == featureCount);
-
-    // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-    features->features = DAWN_UNSAFE_TODO({wgslFeatures, featureCount});
+    features->features = HeapArrayFrom(mWGSLFeatures).MoveToSpan();
 }
 
 void APISupportedWGSLLanguageFeaturesFreeMembers(
diff --git a/src/dawn/native/SharedResourceMemory.cpp b/src/dawn/native/SharedResourceMemory.cpp
index edc187c..e124fdf 100644
--- a/src/dawn/native/SharedResourceMemory.cpp
+++ b/src/dawn/native/SharedResourceMemory.cpp
@@ -38,6 +38,7 @@
 #include "src/dawn/native/Queue.h"
 #include "src/dawn/native/Texture.h"
 #include "src/utils/compiler.h"
+#include "src/utils/heap_array.h"
 
 namespace dawn::native {
 
@@ -335,16 +336,16 @@
 
     // Copy the fences to the output state.
     if (size_t fenceCount = fenceList.size()) {
-        // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-        auto* fences = new SharedFenceBase*[fenceCount];
-        uint64_t* signaledValues = new uint64_t[fenceCount];
+        auto fences = HeapArray<SharedFenceBase*>(fenceCount);
+        auto signaledValues = HeapArray<uint64_t>(fenceCount);
+
         for (size_t i = 0; i < fenceCount; ++i) {
-            DAWN_UNSAFE_TODO(fences[i]) = ReturnToAPI(std::move(fenceList[i].object));
-            DAWN_UNSAFE_TODO(signaledValues[i]) = fenceList[i].signaledValue;
+            fences[i] = ReturnToAPI(std::move(fenceList[i].object));
+            signaledValues[i] = fenceList[i].signaledValue;
         }
 
-        state->fences = DAWN_UNSAFE_TODO({fences, fenceCount});
-        state->signaledValues = DAWN_UNSAFE_TODO({signaledValues, fenceCount});
+        state->fences = std::move(fences).MoveToSpan();
+        state->signaledValues = std::move(signaledValues).MoveToSpan();
     } else {
         state->fences = {};
         state->signaledValues = {};
diff --git a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
index 15ad39f..856e559 100644
--- a/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
+++ b/src/dawn/native/d3d11/PhysicalDeviceD3D11.cpp
@@ -42,6 +42,7 @@
 #include "src/dawn/native/d3d11/PlatformFunctionsD3D11.h"
 #include "src/dawn/native/d3d11/UtilsD3D11.h"
 #include "src/utils/compiler.h"
+#include "src/utils/heap_array.h"
 
 namespace dawn::native::d3d11 {
 
@@ -403,27 +404,27 @@
         // the properties of D3D12 Default/Upload/Readback heaps. The assumption is that these are
         // roughly how D3D11 allocates memory has well.
         if (mDeviceInfo.isUMA) {
-            // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-            auto* heapInfo = new MemoryHeapInfo[1];
-            memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, 1});
+            auto heapInfo = HeapArray<MemoryHeapInfo>(1);
 
             heapInfo[0].size =
                 std::max(mDeviceInfo.dedicatedVideoMemory, mDeviceInfo.sharedSystemMemory);
             heapInfo[0].properties =
                 wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
                 wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+
+            memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
         } else {
-            // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-            auto* heapInfo = new MemoryHeapInfo[2];
-            memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, 2});
+            auto heapInfo = HeapArray<MemoryHeapInfo>(2);
 
             heapInfo[0].size = mDeviceInfo.dedicatedVideoMemory;
             heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
 
-            DAWN_UNSAFE_TODO(heapInfo[1]).size = mDeviceInfo.sharedSystemMemory;
-            DAWN_UNSAFE_TODO(heapInfo[1]).properties =
+            heapInfo[1].size = mDeviceInfo.sharedSystemMemory;
+            heapInfo[1].properties =
                 wgpu::HeapProperty::HostVisible | wgpu::HeapProperty::HostCoherent |
                 wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+
+            memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
         }
     }
     if (auto* d3dProperties = info.Get<AdapterPropertiesD3D>()) {
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index a90b000..1f156db 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -44,6 +44,7 @@
 #include "src/dawn/native/d3d12/PlatformFunctionsD3D12.h"
 #include "src/dawn/native/d3d12/UtilsD3D12.h"
 #include "src/utils/compiler.h"
+#include "src/utils/heap_array.h"
 #include "src/utils/platform.h"
 
 namespace dawn::native::d3d12 {
@@ -983,9 +984,7 @@
         // https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html describes
         // the properties of D3D12 Default/Upload/Readback heaps.
         if (mDeviceInfo.isUMA) {
-            // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-            auto* heapInfo = new MemoryHeapInfo[1];
-            memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, 1});
+            auto heapInfo = HeapArray<MemoryHeapInfo>(1);
 
             heapInfo[0].size =
                 std::max(mDeviceInfo.dedicatedVideoMemory, mDeviceInfo.sharedSystemMemory);
@@ -999,18 +998,20 @@
                     wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
                     wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
             }
+
+            memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
         } else {
-            // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-            auto* heapInfo = new MemoryHeapInfo[2];
-            memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, 2});
+            auto heapInfo = HeapArray<MemoryHeapInfo>(2);
 
             heapInfo[0].size = mDeviceInfo.dedicatedVideoMemory;
             heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
 
-            DAWN_UNSAFE_TODO(heapInfo[1]).size = mDeviceInfo.sharedSystemMemory;
-            DAWN_UNSAFE_TODO(heapInfo[1]).properties =
+            heapInfo[1].size = mDeviceInfo.sharedSystemMemory;
+            heapInfo[1].properties =
                 wgpu::HeapProperty::HostVisible | wgpu::HeapProperty::HostCoherent |
                 wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
+
+            memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
         }
     }
     if (auto* d3dProperties = info.Get<AdapterPropertiesD3D>()) {
@@ -1020,13 +1021,7 @@
     if (auto* subgroupMatrixConfigs = info.Get<AdapterPropertiesSubgroupMatrixConfigs>()) {
         std::vector<SubgroupMatrixConfig> supportedConfigs =
             EnumerateSubgroupMatrixConfigs(toggles);
-        size_t count = supportedConfigs.size();
-        // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-        SubgroupMatrixConfig* configs = new SubgroupMatrixConfig[count];
-        subgroupMatrixConfigs->configs = DAWN_UNSAFE_TODO({configs, supportedConfigs.size()});
-        // TODO(https://crbug.com/524406299): use dawn::Span::CopyFrom.
-        DAWN_UNSAFE_TODO(
-            memcpy(configs, supportedConfigs.data(), count * sizeof(SubgroupMatrixConfig)));
+        subgroupMatrixConfigs->configs = HeapArrayFrom(supportedConfigs).MoveToSpan();
     }
 }
 
diff --git a/src/dawn/native/metal/PhysicalDeviceMTL.mm b/src/dawn/native/metal/PhysicalDeviceMTL.mm
index 1775aca..2d7e995 100644
--- a/src/dawn/native/metal/PhysicalDeviceMTL.mm
+++ b/src/dawn/native/metal/PhysicalDeviceMTL.mm
@@ -1009,9 +1009,7 @@
                                                const TogglesState& toggles) const {
     if (auto* memoryHeapProperties = info.Get<AdapterPropertiesMemoryHeaps>()) {
         if ([*mDevice hasUnifiedMemory]) {
-            // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-            auto* heapInfo = new MemoryHeapInfo[1];
-            memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, 1});
+            auto heapInfo = HeapArray<MemoryHeapInfo>(1);
 
             heapInfo[0].properties =
                 wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
@@ -1028,11 +1026,11 @@
                 // excluding the conditional causes build errors.
                 DAWN_UNREACHABLE();
             }
+
+            memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
         } else {
 #if DAWN_PLATFORM_IS(MACOS)
-            // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-            auto* heapInfo = new MemoryHeapInfo[2];
-            memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, 2});
+            auto heapInfo = HeapArray<MemoryHeapInfo>(2);
 
             heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;
             heapInfo[0].size = [*mDevice recommendedMaxWorkingSetSize];
@@ -1043,10 +1041,12 @@
                                     reinterpret_cast<host_info_t>(&hostInfo), &hostBasicInfoMsg);
             DAWN_CHECK(status == KERN_SUCCESS);
 
-            DAWN_UNSAFE_TODO(heapInfo[1].properties) = wgpu::HeapProperty::HostVisible |
-                                                       wgpu::HeapProperty::HostCoherent |
-                                                       wgpu::HeapProperty::HostCached;
-            DAWN_UNSAFE_TODO(heapInfo[1].size) = hostInfo.max_mem;
+            heapInfo[1].properties = wgpu::HeapProperty::HostVisible |
+                                     wgpu::HeapProperty::HostCoherent |
+                                     wgpu::HeapProperty::HostCached;
+            heapInfo[1].size = hostInfo.max_mem;
+
+            memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
 #else
             DAWN_UNREACHABLE();
 #endif
@@ -1055,9 +1055,7 @@
     if (auto* subgroupMatrixConfigs = info.Get<AdapterPropertiesSubgroupMatrixConfigs>()) {
         DAWN_ASSERT([*mDevice supportsFamily:MTLGPUFamilyApple7]);
 
-        // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-        auto* configs = new SubgroupMatrixConfig[2];
-        subgroupMatrixConfigs->configs = DAWN_UNSAFE_TODO({configs, 2});
+        auto configs = HeapArray<SubgroupMatrixConfig>(2);
 
         configs[0].componentType = wgpu::SubgroupMatrixComponentType::F32;
         configs[0].resultComponentType = wgpu::SubgroupMatrixComponentType::F32;
@@ -1065,11 +1063,13 @@
         configs[0].N = 8;
         configs[0].K = 8;
 
-        DAWN_UNSAFE_TODO(configs[1].componentType) = wgpu::SubgroupMatrixComponentType::F16;
-        DAWN_UNSAFE_TODO(configs[1].resultComponentType) = wgpu::SubgroupMatrixComponentType::F16;
-        DAWN_UNSAFE_TODO(configs[1].M) = 8;
-        DAWN_UNSAFE_TODO(configs[1].N) = 8;
-        DAWN_UNSAFE_TODO(configs[1].K) = 8;
+        configs[1].componentType = wgpu::SubgroupMatrixComponentType::F16;
+        configs[1].resultComponentType = wgpu::SubgroupMatrixComponentType::F16;
+        configs[1].M = 8;
+        configs[1].N = 8;
+        configs[1].K = 8;
+
+        subgroupMatrixConfigs->configs = std::move(configs).MoveToSpan();
     }
 }
 }  // namespace dawn::native::metal
diff --git a/src/dawn/native/null/DeviceNull.cpp b/src/dawn/native/null/DeviceNull.cpp
index 2dfddc0..741bf71 100644
--- a/src/dawn/native/null/DeviceNull.cpp
+++ b/src/dawn/native/null/DeviceNull.cpp
@@ -40,6 +40,7 @@
 #include "src/dawn/native/Surface.h"
 #include "src/dawn/native/TintUtils.h"
 #include "src/utils/compiler.h"
+#include "src/utils/heap_array.h"
 #include "src/utils/numeric.h"
 #include "tint/tint.h"
 
@@ -117,13 +118,13 @@
 void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterInfo>& info,
                                                const TogglesState&) const {
     if (auto* memoryHeapProperties = info.Get<AdapterPropertiesMemoryHeaps>()) {
-        // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-        auto* heapInfo = new MemoryHeapInfo[1];
-        memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, 1});
+        auto heapInfo = HeapArray<MemoryHeapInfo>(1);
 
         heapInfo[0].size = 1024ULL * 1024 * 1024;
         heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
                                  wgpu::HeapProperty::HostCached;
+
+        memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
     }
     if (auto* d3dProperties = info.Get<AdapterPropertiesD3D>()) {
         d3dProperties->shaderModel = 0;
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 5552bbe..6987388 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -34,6 +34,7 @@
 #include <vector>
 
 #include "dawn/platform/DawnPlatform.h"
+#include "src/dawn/common/Enumerator.h"
 #include "src/dawn/common/GPUInfo.h"
 #include "src/dawn/native/ChainUtils.h"
 #include "src/dawn/native/Error.h"
@@ -1668,35 +1669,30 @@
 void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterInfo>& info,
                                                const TogglesState& toggles) const {
     if (auto* memoryHeapProperties = info.Get<AdapterPropertiesMemoryHeaps>()) {
-        // TODO(https://crbug.com/512465980): Use dawn::HeapArray and Enumerate to loop over it.
-        size_t count = mDeviceInfo.memoryHeaps.size();
-        auto* heapInfo = new MemoryHeapInfo[count];
-        memoryHeapProperties->heapInfo = DAWN_UNSAFE_TODO({heapInfo, count});
+        auto heapInfo = HeapArray<MemoryHeapInfo>(mDeviceInfo.memoryHeaps.size());
 
-        for (size_t i = 0; i < count; ++i) {
-            DAWN_UNSAFE_TODO(heapInfo[i]).size = mDeviceInfo.memoryHeaps[i].size;
-            DAWN_UNSAFE_TODO(heapInfo[i]).properties = {};
+        for (auto [i, heap] : Enumerate(heapInfo)) {
+            heap.size = mDeviceInfo.memoryHeaps[i].size;
+            heap.properties = {};
             if (mDeviceInfo.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
-                DAWN_UNSAFE_TODO(heapInfo[i]).properties |= wgpu::HeapProperty::DeviceLocal;
+                heap.properties |= wgpu::HeapProperty::DeviceLocal;
             }
         }
         for (const auto& memoryType : mDeviceInfo.memoryTypes) {
             if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
-                DAWN_UNSAFE_TODO(heapInfo[memoryType.heapIndex]).properties |=
-                    wgpu::HeapProperty::HostVisible;
+                heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostVisible;
             }
             if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
-                DAWN_UNSAFE_TODO(heapInfo[memoryType.heapIndex]).properties |=
-                    wgpu::HeapProperty::HostCoherent;
+                heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostCoherent;
             }
             if (memoryType.propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
-                DAWN_UNSAFE_TODO(heapInfo[memoryType.heapIndex]).properties |=
-                    wgpu::HeapProperty::HostCached;
+                heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostCached;
             } else {
-                DAWN_UNSAFE_TODO(heapInfo[memoryType.heapIndex]).properties |=
-                    wgpu::HeapProperty::HostUncached;
+                heapInfo[memoryType.heapIndex].properties |= wgpu::HeapProperty::HostUncached;
             }
         }
+
+        memoryHeapProperties->heapInfo = std::move(heapInfo).MoveToSpan();
     }
     if (auto* vkProperties = info.Get<AdapterPropertiesVk>()) {
         vkProperties->driverVersion = mDeviceInfo.properties.driverVersion;
@@ -1714,13 +1710,7 @@
     if (auto* subgroupMatrixConfigs = info.Get<AdapterPropertiesSubgroupMatrixConfigs>()) {
         std::vector<SubgroupMatrixConfig> supportedConfigs =
             EnumerateSubgroupMatrixConfigs(toggles);
-        size_t count = supportedConfigs.size();
-        // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-        SubgroupMatrixConfig* configs = new SubgroupMatrixConfig[count];
-        subgroupMatrixConfigs->configs = DAWN_UNSAFE_TODO({configs, supportedConfigs.size()});
-        // TODO(https://crbug.com/524406299): use dawn::Span::CopyFrom.
-        DAWN_UNSAFE_TODO(
-            memcpy(configs, supportedConfigs.data(), count * sizeof(SubgroupMatrixConfig)));
+        subgroupMatrixConfigs->configs = HeapArrayFrom(supportedConfigs).MoveToSpan();
     }
 }
 
@@ -1735,16 +1725,14 @@
         auto drmFormatModifiers =
             GetFormatModifierProps(mVulkanInstance->GetFunctions(), mVkPhysicalDevice, vk_format);
         if (!drmFormatModifiers.empty()) {
-            size_t count = drmFormatModifiers.size();
-            // TODO(https://crbug.com/512465980): Use dawn::HeapArray
-            auto* properties = new DawnDrmFormatProperties[count];
-            drmCapabilities->properties = DAWN_UNSAFE_TODO({properties, count});
+            auto properties = HeapArray<DawnDrmFormatProperties>(drmFormatModifiers.size());
 
-            for (size_t i = 0; i < count; i++) {
-                DAWN_UNSAFE_TODO(properties[i]).modifier = drmFormatModifiers[i].drmFormatModifier;
-                DAWN_UNSAFE_TODO(properties[i]).modifierPlaneCount =
-                    drmFormatModifiers[i].drmFormatModifierPlaneCount;
+            for (auto [i, property] : Enumerate(properties)) {
+                property.modifier = drmFormatModifiers[i].drmFormatModifier;
+                property.modifierPlaneCount = drmFormatModifiers[i].drmFormatModifierPlaneCount;
             }
+
+            drmCapabilities->properties = std::move(properties).MoveToSpan();
         }
     }
 }
diff --git a/src/utils/heap_array.h b/src/utils/heap_array.h
index d5ad245..98113f4 100644
--- a/src/utils/heap_array.h
+++ b/src/utils/heap_array.h
@@ -228,8 +228,7 @@
 
     Index size = checked_cast<Index>(std::ranges::size(src));
 
-    // SAFETY: Initialized by the copy.
-    auto result = DAWN_UNSAFE_BUFFERS(HeapArray<Index, Value>::Uninit(size));
+    auto result = HeapArray<Index, Value>(size);
     std::ranges::copy(src, result.begin());
     return result;
 }