Use more ityp helpers for ColorAttachmentIndex.

Bug: dawn:2222
Change-Id: I6e7c422b2566749085edca1e901546cd5e674a16
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/161690
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/AttachmentState.cpp b/src/dawn/native/AttachmentState.cpp
index c7ba823..fab0c85 100644
--- a/src/dawn/native/AttachmentState.cpp
+++ b/src/dawn/native/AttachmentState.cpp
@@ -28,6 +28,8 @@
 #include "dawn/native/AttachmentState.h"
 
 #include "dawn/common/BitSetIterator.h"
+#include "dawn/common/Enumerator.h"
+#include "dawn/common/ityp_span.h"
 #include "dawn/native/ChainUtils_autogen.h"
 #include "dawn/native/Device.h"
 #include "dawn/native/ObjectContentHasher.h"
@@ -40,9 +42,10 @@
                                  const RenderBundleEncoderDescriptor* descriptor)
     : ObjectBase(device), mSampleCount(descriptor->sampleCount) {
     DAWN_ASSERT(descriptor->colorFormatCount <= kMaxColorAttachments);
-    for (ColorAttachmentIndex i(uint8_t(0));
-         i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->colorFormatCount)); ++i) {
-        wgpu::TextureFormat format = descriptor->colorFormats[static_cast<uint8_t>(i)];
+    auto colorFormats = ityp::SpanFromUntyped<ColorAttachmentIndex>(descriptor->colorFormats,
+                                                                    descriptor->colorFormatCount);
+
+    for (auto [i, format] : Enumerate(colorFormats)) {
         if (format != wgpu::TextureFormat::Undefined) {
             mColorAttachmentsSet.set(i);
             mColorFormats[i] = format;
@@ -68,11 +71,11 @@
 
     if (descriptor->fragment != nullptr) {
         DAWN_ASSERT(descriptor->fragment->targetCount <= kMaxColorAttachments);
-        for (ColorAttachmentIndex i(uint8_t(0));
-             i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->fragment->targetCount));
-             ++i) {
-            wgpu::TextureFormat format =
-                descriptor->fragment->targets[static_cast<uint8_t>(i)].format;
+        auto targets = ityp::SpanFromUntyped<ColorAttachmentIndex>(
+            descriptor->fragment->targets, descriptor->fragment->targetCount);
+
+        for (auto [i, target] : Enumerate(targets)) {
+            wgpu::TextureFormat format = target.format;
             if (format != wgpu::TextureFormat::Undefined) {
                 mColorAttachmentsSet.set(i);
                 mColorFormats[i] = format;
@@ -91,10 +94,9 @@
 
 AttachmentState::AttachmentState(DeviceBase* device, const RenderPassDescriptor* descriptor)
     : ObjectBase(device) {
-    for (ColorAttachmentIndex i(uint8_t(0));
-         i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->colorAttachmentCount)); ++i) {
-        const RenderPassColorAttachment& colorAttachment =
-            descriptor->colorAttachments[static_cast<uint8_t>(i)];
+    auto colorAttachments = ityp::SpanFromUntyped<ColorAttachmentIndex>(
+        descriptor->colorAttachments, descriptor->colorAttachmentCount);
+    for (auto [i, colorAttachment] : Enumerate(colorAttachments)) {
         TextureViewBase* attachment = colorAttachment.view;
         if (attachment == nullptr) {
             continue;
@@ -181,7 +183,7 @@
     }
 
     // Check color formats
-    for (ColorAttachmentIndex i : IterateBitSet(a->mColorAttachmentsSet)) {
+    for (auto i : IterateBitSet(a->mColorAttachmentsSet)) {
         if (a->mColorFormats[i] != b->mColorFormats[i]) {
             return false;
         }
@@ -223,7 +225,7 @@
 
     // Hash color formats
     HashCombine(&hash, mColorAttachmentsSet);
-    for (ColorAttachmentIndex i : IterateBitSet(mColorAttachmentsSet)) {
+    for (auto i : IterateBitSet(mColorAttachmentsSet)) {
         HashCombine(&hash, mColorFormats[i]);
     }
 
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index 53940d9..52842a4 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -35,6 +35,7 @@
 #include <vector>
 
 #include "dawn/common/BitSetIterator.h"
+#include "dawn/common/Enumerator.h"
 #include "dawn/native/ChainUtils.h"
 #include "dawn/native/Device.h"
 #include "dawn/native/ObjectBase.h"
@@ -500,8 +501,8 @@
 bool CheckBufferBindingsFirst(ityp::span<BindingIndex, const BindingInfo> bindings) {
     BindingIndex lastBufferIndex{0};
     BindingIndex firstNonBufferIndex = std::numeric_limits<BindingIndex>::max();
-    for (BindingIndex i{0}; i < bindings.size(); ++i) {
-        if (bindings[i].bindingType == BindingInfoType::Buffer) {
+    for (auto [i, binding] : Enumerate(bindings)) {
+        if (binding.bindingType == BindingInfoType::Buffer) {
             lastBufferIndex = std::max(i, lastBufferIndex);
         } else {
             firstNonBufferIndex = std::min(i, firstNonBufferIndex);
diff --git a/src/dawn/native/CommandBuffer.cpp b/src/dawn/native/CommandBuffer.cpp
index 93bdc4d..2b682e2 100644
--- a/src/dawn/native/CommandBuffer.cpp
+++ b/src/dawn/native/CommandBuffer.cpp
@@ -148,8 +148,7 @@
 }
 
 void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass) {
-    for (ColorAttachmentIndex i :
-         IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+    for (auto i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
         auto& attachmentInfo = renderPass->colorAttachments[i];
         TextureViewBase* view = attachmentInfo.view.Get();
         bool hasResolveTarget = attachmentInfo.resolveTarget != nullptr;
diff --git a/src/dawn/native/CommandEncoder.cpp b/src/dawn/native/CommandEncoder.cpp
index 0bd5859..6ce0913 100644
--- a/src/dawn/native/CommandEncoder.cpp
+++ b/src/dawn/native/CommandEncoder.cpp
@@ -33,6 +33,7 @@
 #include <vector>
 
 #include "dawn/common/BitSetIterator.h"
+#include "dawn/common/Enumerator.h"
 #include "dawn/common/Math.h"
 #include "dawn/native/ApplyClearColorValueWithDrawHelper.h"
 #include "dawn/native/BindGroup.h"
@@ -647,13 +648,15 @@
         "Color attachment count (%u) exceeds the maximum number of color attachments (%u).",
         descriptor->colorAttachmentCount, maxColorAttachments);
 
+    auto colorAttachments = ityp::SpanFromUntyped<ColorAttachmentIndex>(
+        descriptor->colorAttachments, descriptor->colorAttachmentCount);
     ColorAttachmentFormats colorAttachmentFormats;
-    for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
-        DAWN_TRY_CONTEXT(ValidateRenderPassColorAttachment(device, descriptor->colorAttachments[i],
-                                                           usageValidationMode, validationState),
+    for (auto [i, attachment] : Enumerate(colorAttachments)) {
+        DAWN_TRY_CONTEXT(ValidateRenderPassColorAttachment(device, attachment, usageValidationMode,
+                                                           validationState),
                          "validating colorAttachments[%u].", i);
-        if (descriptor->colorAttachments[i].view) {
-            colorAttachmentFormats->push_back(&descriptor->colorAttachments[i].view->GetFormat());
+        if (attachment.view) {
+            colorAttachmentFormats->push_back(&attachment.view->GetFormat());
         }
     }
     DAWN_TRY_CONTEXT(ValidateColorAttachmentBytesPerSample(device, colorAttachmentFormats),
@@ -1092,43 +1095,43 @@
             cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
             attachmentState = cmd->attachmentState;
 
-            for (ColorAttachmentIndex index :
-                 IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
-                uint8_t i = static_cast<uint8_t>(index);
+            auto descColorAttachments = ityp::SpanFromUntyped<ColorAttachmentIndex>(
+                descriptor->colorAttachments, descriptor->colorAttachmentCount);
+            for (auto i : IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
+                auto& descColorAttachment = descColorAttachments[i];
+                auto& cmdColorAttachment = cmd->colorAttachments[i];
+
                 TextureViewBase* colorTarget;
                 TextureViewBase* resolveTarget;
 
                 if (validationState.GetImplicitSampleCount() <= 1) {
-                    colorTarget = descriptor->colorAttachments[i].view;
-                    resolveTarget = descriptor->colorAttachments[i].resolveTarget;
+                    colorTarget = descColorAttachment.view;
+                    resolveTarget = descColorAttachment.resolveTarget;
 
-                    cmd->colorAttachments[index].view = colorTarget;
-                    cmd->colorAttachments[index].depthSlice =
-                        descriptor->colorAttachments[i].depthSlice;
-                    cmd->colorAttachments[index].loadOp = descriptor->colorAttachments[i].loadOp;
-                    cmd->colorAttachments[index].storeOp = descriptor->colorAttachments[i].storeOp;
+                    cmdColorAttachment.view = colorTarget;
+                    cmdColorAttachment.depthSlice = descColorAttachment.depthSlice;
+                    cmdColorAttachment.loadOp = descColorAttachment.loadOp;
+                    cmdColorAttachment.storeOp = descColorAttachment.storeOp;
                 } else {
                     // We use an implicit MSAA texture and resolve to the client supplied
                     // attachment.
-                    resolveTarget = descriptor->colorAttachments[i].view;
+                    resolveTarget = descColorAttachment.view;
                     Ref<TextureViewBase> implicitMSAATargetRef;
                     DAWN_TRY_ASSIGN(implicitMSAATargetRef,
                                     device->CreateImplicitMSAARenderTextureViewFor(
                                         resolveTarget, validationState.GetImplicitSampleCount()));
                     colorTarget = implicitMSAATargetRef.Get();
 
-                    cmd->colorAttachments[index].view = std::move(implicitMSAATargetRef);
+                    cmdColorAttachment.view = std::move(implicitMSAATargetRef);
                     // Without explicitly setting depthSlice to zero, its value would be undefined.
-                    cmd->colorAttachments[index].depthSlice = 0;
-                    cmd->colorAttachments[index].loadOp = wgpu::LoadOp::Clear;
-                    cmd->colorAttachments[index].storeOp = wgpu::StoreOp::Discard;
+                    cmdColorAttachment.depthSlice = 0;
+                    cmdColorAttachment.loadOp = wgpu::LoadOp::Clear;
+                    cmdColorAttachment.storeOp = wgpu::StoreOp::Discard;
                 }
 
-                cmd->colorAttachments[index].resolveTarget = resolveTarget;
-
-                Color color = descriptor->colorAttachments[i].clearValue;
-                cmd->colorAttachments[index].clearColor =
-                    ClampClearColorValueToLegalRange(color, colorTarget->GetFormat());
+                cmdColorAttachment.resolveTarget = resolveTarget;
+                cmdColorAttachment.clearColor = ClampClearColorValueToLegalRange(
+                    descColorAttachment.clearValue, colorTarget->GetFormat());
 
                 usageTracker.TextureViewUsedAs(colorTarget, wgpu::TextureUsage::RenderAttachment);
 
@@ -1325,8 +1328,7 @@
 
         // This workaround needs to apply if there are multiple MSAA color targets (checked above)
         // and at least one resolve target.
-        for (ColorAttachmentIndex i :
-             IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
             if (cmd->colorAttachments[i].resolveTarget.Get() != nullptr) {
                 splitResolvesIntoSeparatePasses = true;
                 break;
@@ -1336,8 +1338,7 @@
         if (splitResolvesIntoSeparatePasses) {
             std::vector<TemporaryResolveAttachment> temporaryResolveAttachments;
 
-            for (ColorAttachmentIndex i :
-                 IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
+            for (auto i : IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
                 auto& attachmentInfo = cmd->colorAttachments[i];
                 TextureViewBase* resolveTarget = attachmentInfo.resolveTarget.Get();
                 if (resolveTarget != nullptr) {
@@ -1392,8 +1393,7 @@
     if (device->IsToggleEnabled(Toggle::AlwaysResolveIntoZeroLevelAndLayer)) {
         std::vector<TemporaryResolveAttachment> temporaryResolveAttachments;
 
-        for (ColorAttachmentIndex index :
-             IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
+        for (auto index : IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
             TextureViewBase* resolveTarget = cmd->colorAttachments[index].resolveTarget.Get();
 
             if (resolveTarget != nullptr && (resolveTarget->GetBaseMipLevel() != 0 ||
diff --git a/src/dawn/native/IntegerTypes.h b/src/dawn/native/IntegerTypes.h
index f73c9af..913aba7 100644
--- a/src/dawn/native/IntegerTypes.h
+++ b/src/dawn/native/IntegerTypes.h
@@ -43,11 +43,9 @@
 using BindingIndex = TypedInteger<struct BindingIndexT, uint32_t>;
 
 using BindGroupIndex = TypedInteger<struct BindGroupIndexT, uint32_t>;
-
 constexpr BindGroupIndex kMaxBindGroupsTyped = BindGroupIndex(kMaxBindGroups);
 
 using ColorAttachmentIndex = TypedInteger<struct ColorAttachmentIndexT, uint8_t>;
-
 constexpr ColorAttachmentIndex kMaxColorAttachmentsTyped =
     ColorAttachmentIndex(kMaxColorAttachments);
 
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index fdf2f1c..4e5f572 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -31,6 +31,7 @@
 #include <cmath>
 
 #include "dawn/common/BitSetIterator.h"
+#include "dawn/common/Enumerator.h"
 #include "dawn/common/ityp_span.h"
 #include "dawn/native/ChainUtils.h"
 #include "dawn/native/CommandValidation.h"
@@ -582,13 +583,13 @@
     DAWN_INVALID_IF(descriptor->targetCount > maxColorAttachments,
                     "Number of targets (%u) exceeds the maximum (%u).", descriptor->targetCount,
                     maxColorAttachments);
-    ityp::span<ColorAttachmentIndex, const ColorTargetState> targets(
-        descriptor->targets, ColorAttachmentIndex(uint8_t(descriptor->targetCount)));
+    auto targets =
+        ityp::SpanFromUntyped<ColorAttachmentIndex>(descriptor->targets, descriptor->targetCount);
 
     ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> targetMask;
-    for (ColorAttachmentIndex i{}; i < targets.size(); ++i) {
-        if (targets[i].format == wgpu::TextureFormat::Undefined) {
-            DAWN_INVALID_IF(targets[i].blend,
+    for (auto [i, target] : Enumerate(targets)) {
+        if (target.format == wgpu::TextureFormat::Undefined) {
+            DAWN_INVALID_IF(target.blend,
                             "Color target[%u] blend state is set when the format is undefined.", i);
         } else {
             targetMask.set(i);
@@ -596,7 +597,7 @@
     }
 
     ColorAttachmentFormats colorAttachmentFormats;
-    for (ColorAttachmentIndex i : IterateBitSet(targetMask)) {
+    for (auto i : IterateBitSet(targetMask)) {
         const Format* format;
         DAWN_TRY_ASSIGN(format, device->GetInternalFormat(targets[i].format));
 
@@ -649,7 +650,7 @@
         // Check that all the color target states match.
         ColorAttachmentIndex firstColorTargetIndex{};
         const ColorTargetState* firstColorTargetState = nullptr;
-        for (ColorAttachmentIndex i : IterateBitSet(targetMask)) {
+        for (auto i : IterateBitSet(targetMask)) {
             if (!firstColorTargetState) {
                 firstColorTargetState = &targets[i];
                 firstColorTargetIndex = i;
@@ -944,7 +945,7 @@
         mDepthStencil.depthBiasClamp = 0.0f;
     }
 
-    for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
+    for (auto i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
         // Vertex-only render pipeline have no color attachment. For a render pipeline with
         // color attachments, there must be a valid FragmentState.
         DAWN_ASSERT(descriptor->fragment != nullptr);
@@ -1171,7 +1172,7 @@
     recorder.Record(mAttachmentState->GetContentHash());
 
     // Record attachments
-    for (ColorAttachmentIndex i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
+    for (auto i : IterateBitSet(mAttachmentState->GetColorAttachmentsMask())) {
         const ColorTargetState& desc = *GetColorTargetState(i);
         recorder.Record(desc.writeMask);
         if (desc.blend != nullptr) {
@@ -1231,8 +1232,7 @@
     }
 
     if (a->mAttachmentState.Get() != nullptr) {
-        for (ColorAttachmentIndex i :
-             IterateBitSet(a->mAttachmentState->GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(a->mAttachmentState->GetColorAttachmentsMask())) {
             const ColorTargetState& descA = *a->GetColorTargetState(i);
             const ColorTargetState& descB = *b->GetColorTargetState(i);
             if (descA.writeMask != descB.writeMask) {
diff --git a/src/dawn/native/d3d11/CommandBufferD3D11.cpp b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
index 04f5c5b..4d1a722 100644
--- a/src/dawn/native/d3d11/CommandBufferD3D11.cpp
+++ b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
@@ -592,10 +592,9 @@
     // Hold ID3D11RenderTargetView ComPtr to make attachments alive.
     ityp::array<ColorAttachmentIndex, ID3D11RenderTargetView*, kMaxColorAttachments>
         d3d11RenderTargetViews = {};
-    ColorAttachmentIndex attachmentCount(uint8_t(0));
+    ColorAttachmentIndex attachmentCount{};
     // TODO(dawn:1815): Shrink the sparse attachments to accommodate more UAVs.
-    for (ColorAttachmentIndex i :
-         IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+    for (auto i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
         TextureView* colorTextureView = ToBackend(renderPass->colorAttachments[i].view.Get());
         DAWN_TRY_ASSIGN(d3d11RenderTargetViews[i],
                         colorTextureView->GetOrCreateD3D11RenderTargetView());
@@ -604,8 +603,7 @@
                 ConvertToFloatColor(renderPass->colorAttachments[i].clearColor);
             d3d11DeviceContext->ClearRenderTargetView(d3d11RenderTargetViews[i], clearColor.data());
         }
-        attachmentCount = i;
-        attachmentCount++;
+        attachmentCount = ityp::PlusOne(i);
     }
 
     ID3D11DepthStencilView* d3d11DepthStencilView = nullptr;
@@ -819,7 +817,7 @@
                 }
 
                 // Resolve multisampled textures.
-                for (ColorAttachmentIndex i :
+                for (auto i :
                      IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
                     const auto& attachment = renderPass->colorAttachments[i];
                     if (!attachment.resolveTarget.Get()) {
diff --git a/src/dawn/native/d3d11/RenderPipelineD3D11.cpp b/src/dawn/native/d3d11/RenderPipelineD3D11.cpp
index dc0f260..48ab630 100644
--- a/src/dawn/native/d3d11/RenderPipelineD3D11.cpp
+++ b/src/dawn/native/d3d11/RenderPipelineD3D11.cpp
@@ -34,6 +34,7 @@
 #include <optional>
 #include <utility>
 
+#include "dawn/common/Range.h"
 #include "dawn/native/CreatePipelineAsyncTask.h"
 #include "dawn/native/d3d/D3DError.h"
 #include "dawn/native/d3d/ShaderUtils.h"
@@ -357,10 +358,10 @@
     blendDesc.IndependentBlendEnable = TRUE;
 
     static_assert(kMaxColorAttachments == std::size(blendDesc.RenderTarget));
-    for (ColorAttachmentIndex i(0Ui8); i < ColorAttachmentIndex(kMaxColorAttachments); ++i) {
+    for (auto i : Range(kMaxColorAttachmentsTyped)) {
         D3D11_RENDER_TARGET_BLEND_DESC& rtBlendDesc =
             blendDesc.RenderTarget[static_cast<uint8_t>(i)];
-        const ColorTargetState* descriptor = GetColorTargetState(ColorAttachmentIndex(i));
+        const ColorTargetState* descriptor = GetColorTargetState(i);
         rtBlendDesc.BlendEnable = descriptor->blend != nullptr;
         if (rtBlendDesc.BlendEnable) {
             rtBlendDesc.SrcBlend = D3DBlendFactor(descriptor->blend->color.srcFactor);
diff --git a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
index 448a9a6..5a1f4a5 100644
--- a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
+++ b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
@@ -399,9 +399,8 @@
         descriptorD3D12.RTVFormats[i] = DXGI_FORMAT_UNKNOWN;
         descriptorD3D12.BlendState.RenderTarget[i].LogicOp = D3D12_LOGIC_OP_NOOP;
     }
-    ColorAttachmentIndex highestColorAttachmentIndexPlusOne =
-        GetHighestBitIndexPlusOne(GetColorAttachmentsMask());
-    for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
+    auto highestColorAttachmentIndexPlusOne = GetHighestBitIndexPlusOne(GetColorAttachmentsMask());
+    for (auto i : IterateBitSet(GetColorAttachmentsMask())) {
         descriptorD3D12.RTVFormats[static_cast<uint8_t>(i)] =
             d3d::DXGITextureFormat(GetColorAttachmentFormat(i));
         descriptorD3D12.BlendState.RenderTarget[static_cast<uint8_t>(i)] =
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm
index 62c4032..22f0ce5 100644
--- a/src/dawn/native/metal/CommandBufferMTL.mm
+++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -179,8 +179,7 @@
     NSRef<MTLRenderPassDescriptor> descriptorRef = [MTLRenderPassDescriptor renderPassDescriptor];
     MTLRenderPassDescriptor* descriptor = descriptorRef.Get();
 
-    for (ColorAttachmentIndex attachment :
-         IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+    for (auto attachment : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
         uint8_t i = static_cast<uint8_t>(attachment);
         auto& attachmentInfo = renderPass->colorAttachments[attachment];
 
diff --git a/src/dawn/native/metal/RenderPipelineMTL.mm b/src/dawn/native/metal/RenderPipelineMTL.mm
index d4a2a76..7c65a35 100644
--- a/src/dawn/native/metal/RenderPipelineMTL.mm
+++ b/src/dawn/native/metal/RenderPipelineMTL.mm
@@ -402,7 +402,7 @@
         }
 
         const auto& fragmentOutputMask = fragmentStage.metadata->fragmentOutputMask;
-        for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(GetColorAttachmentsMask())) {
             descriptorMTL.colorAttachments[static_cast<uint8_t>(i)].pixelFormat =
                 MetalPixelFormat(GetDevice(), GetColorAttachmentFormat(i));
             const ColorTargetState* descriptor = GetColorTargetState(i);
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index 7682db7..ad8824d 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -492,8 +492,7 @@
     GLuint readFbo = 0;
     GLuint writeFbo = 0;
 
-    for (ColorAttachmentIndex i :
-         IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+    for (auto i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
         if (renderPass->colorAttachments[i].resolveTarget != nullptr) {
             if (readFbo == 0) {
                 DAWN_ASSERT(writeFbo == 0);
@@ -991,17 +990,15 @@
 
         // Construct GL framebuffer
 
-        ColorAttachmentIndex attachmentCount(uint8_t(0));
-        for (ColorAttachmentIndex i :
-             IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+        ColorAttachmentIndex attachmentCount{};
+        for (auto i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
             TextureView* textureView = ToBackend(renderPass->colorAttachments[i].view.Get());
             GLenum glAttachment = GL_COLOR_ATTACHMENT0 + static_cast<uint8_t>(i);
 
             // Attach color buffers.
             textureView->BindToFramebuffer(GL_DRAW_FRAMEBUFFER, glAttachment);
             drawBuffers[i] = glAttachment;
-            attachmentCount = i;
-            attachmentCount++;
+            attachmentCount = ityp::PlusOne(i);
         }
         gl.DrawBuffers(static_cast<uint8_t>(attachmentCount), drawBuffers.data());
 
@@ -1037,8 +1034,7 @@
 
     // Clear framebuffer attachments as needed
     {
-        for (ColorAttachmentIndex index :
-             IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+        for (auto index : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
             uint8_t i = static_cast<uint8_t>(index);
             auto* attachmentInfo = &renderPass->colorAttachments[index];
 
@@ -1269,7 +1265,7 @@
             case Command::EndRenderPass: {
                 mCommands.NextCommand<EndRenderPassCmd>();
 
-                for (ColorAttachmentIndex i :
+                for (auto i :
                      IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
                     TextureView* textureView =
                         ToBackend(renderPass->colorAttachments[i].view.Get());
diff --git a/src/dawn/native/opengl/RenderPipelineGL.cpp b/src/dawn/native/opengl/RenderPipelineGL.cpp
index 34239d1..2bd44a8 100644
--- a/src/dawn/native/opengl/RenderPipelineGL.cpp
+++ b/src/dawn/native/opengl/RenderPipelineGL.cpp
@@ -338,12 +338,12 @@
     }
 
     if (!GetDevice()->IsToggleEnabled(Toggle::DisableIndexedDrawBuffers)) {
-        for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
+        for (auto attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
             ApplyColorState(gl, attachmentSlot, GetColorTargetState(attachmentSlot));
         }
     } else {
         const ColorTargetState* prevDescriptor = nullptr;
-        for (ColorAttachmentIndex attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
+        for (auto attachmentSlot : IterateBitSet(GetColorAttachmentsMask())) {
             const ColorTargetState* descriptor = GetColorTargetState(attachmentSlot);
             if (!prevDescriptor) {
                 ApplyColorState(gl, descriptor);
diff --git a/src/dawn/native/vulkan/CommandBufferVk.cpp b/src/dawn/native/vulkan/CommandBufferVk.cpp
index 3391b44..afe880d 100644
--- a/src/dawn/native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn/native/vulkan/CommandBufferVk.cpp
@@ -272,8 +272,7 @@
     {
         RenderPassCacheQuery query;
 
-        for (ColorAttachmentIndex i :
-             IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
             const auto& attachmentInfo = renderPass->colorAttachments[i];
             bool hasResolveTarget = attachmentInfo.resolveTarget != nullptr;
 
@@ -304,8 +303,7 @@
         // Fill in the attachment info that will be chained in the framebuffer create info.
         std::array<VkImageView, kMaxColorAttachments * 2 + 1> attachments;
 
-        for (ColorAttachmentIndex i :
-             IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
             auto& attachmentInfo = renderPass->colorAttachments[i];
             TextureView* view = ToBackend(attachmentInfo.view.Get());
             if (view == nullptr) {
@@ -355,8 +353,7 @@
             attachmentCount++;
         }
 
-        for (ColorAttachmentIndex i :
-             IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
             if (renderPass->colorAttachments[i].resolveTarget != nullptr) {
                 TextureView* view = ToBackend(renderPass->colorAttachments[i].resolveTarget.Get());
 
diff --git a/src/dawn/native/vulkan/RenderPassCache.cpp b/src/dawn/native/vulkan/RenderPassCache.cpp
index 872b0a1..6873773 100644
--- a/src/dawn/native/vulkan/RenderPassCache.cpp
+++ b/src/dawn/native/vulkan/RenderPassCache.cpp
@@ -28,7 +28,9 @@
 #include "dawn/native/vulkan/RenderPassCache.h"
 
 #include "dawn/common/BitSetIterator.h"
+#include "dawn/common/Enumerator.h"
 #include "dawn/common/HashUtils.h"
+#include "dawn/common/Range.h"
 #include "dawn/native/vulkan/DeviceVk.h"
 #include "dawn/native/vulkan/TextureVk.h"
 #include "dawn/native/vulkan/VulkanError.h"
@@ -138,7 +140,7 @@
         resolveAttachmentRefs;
     VkAttachmentReference depthStencilAttachmentRef;
 
-    for (ColorAttachmentIndex i(uint8_t(0)); i < kMaxColorAttachmentsTyped; i++) {
+    for (auto i : Range(kMaxColorAttachmentsTyped)) {
         colorAttachmentRefs[i].attachment = VK_ATTACHMENT_UNUSED;
         resolveAttachmentRefs[i].attachment = VK_ATTACHMENT_UNUSED;
         // The Khronos Vulkan validation layer will complain if not set
@@ -155,7 +157,7 @@
 
     uint32_t attachmentCount = 0;
     ColorAttachmentIndex highestColorAttachmentIndexPlusOne(static_cast<uint8_t>(0));
-    for (ColorAttachmentIndex i : IterateBitSet(query.colorMask)) {
+    for (auto i : IterateBitSet(query.colorMask)) {
         auto& attachmentRef = colorAttachmentRefs[i];
         auto& attachmentDesc = attachmentDescs[attachmentCount];
 
@@ -204,7 +206,7 @@
     }
 
     uint32_t resolveAttachmentCount = 0;
-    for (ColorAttachmentIndex i : IterateBitSet(query.resolveTargetMask)) {
+    for (auto i : IterateBitSet(query.resolveTargetMask)) {
         auto& attachmentRef = resolveAttachmentRefs[i];
         auto& attachmentDesc = attachmentDescs[attachmentCount];
 
@@ -273,7 +275,7 @@
 
     HashCombine(&hash, Hash(query.resolveTargetMask));
 
-    for (ColorAttachmentIndex i : IterateBitSet(query.colorMask)) {
+    for (auto i : IterateBitSet(query.colorMask)) {
         HashCombine(&hash, query.colorFormats[i], query.colorLoadOp[i], query.colorStoreOp[i]);
     }
 
@@ -303,7 +305,7 @@
         return false;
     }
 
-    for (ColorAttachmentIndex i : IterateBitSet(a.colorMask)) {
+    for (auto i : IterateBitSet(a.colorMask)) {
         if ((a.colorFormats[i] != b.colorFormats[i]) || (a.colorLoadOp[i] != b.colorLoadOp[i]) ||
             (a.colorStoreOp[i] != b.colorStoreOp[i])) {
             return false;
diff --git a/src/dawn/native/vulkan/RenderPipelineVk.cpp b/src/dawn/native/vulkan/RenderPipelineVk.cpp
index c7ad09f..5e54c9a 100644
--- a/src/dawn/native/vulkan/RenderPipelineVk.cpp
+++ b/src/dawn/native/vulkan/RenderPipelineVk.cpp
@@ -490,9 +490,9 @@
 
         const auto& fragmentOutputMask =
             GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputMask;
-        ColorAttachmentIndex highestColorAttachmentIndexPlusOne =
+        auto highestColorAttachmentIndexPlusOne =
             GetHighestBitIndexPlusOne(GetColorAttachmentsMask());
-        for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(GetColorAttachmentsMask())) {
             const ColorTargetState* target = GetColorTargetState(i);
             colorBlendAttachments[i] = ComputeColorDesc(target, fragmentOutputMask[i]);
         }
@@ -533,7 +533,7 @@
     {
         RenderPassCacheQuery query;
 
-        for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
+        for (auto i : IterateBitSet(GetColorAttachmentsMask())) {
             query.SetColor(i, GetColorAttachmentFormat(i), wgpu::LoadOp::Load, wgpu::StoreOp::Store,
                            false);
         }
diff --git a/src/dawn/native/vulkan/StreamImplVk.cpp b/src/dawn/native/vulkan/StreamImplVk.cpp
index 428e822..427a8ff 100644
--- a/src/dawn/native/vulkan/StreamImplVk.cpp
+++ b/src/dawn/native/vulkan/StreamImplVk.cpp
@@ -322,7 +322,7 @@
     // Manually iterate the color attachment indices and their corresponding format/load/store
     // ops because the data is sparse and may be uninitialized. Since we serialize the colorMask
     // member above, serializing sparse data should be fine here.
-    for (ColorAttachmentIndex i : IterateBitSet(t.colorMask)) {
+    for (auto i : IterateBitSet(t.colorMask)) {
         StreamIn(sink, t.colorFormats[i], t.colorLoadOp[i], t.colorStoreOp[i]);
     }
 
diff --git a/src/dawn/native/webgpu_absl_format.cpp b/src/dawn/native/webgpu_absl_format.cpp
index 1abc5c7..68f5cf1 100644
--- a/src/dawn/native/webgpu_absl_format.cpp
+++ b/src/dawn/native/webgpu_absl_format.cpp
@@ -230,10 +230,10 @@
 
     s->Append("{ colorFormats: [");
 
-    ColorAttachmentIndex nextColorIndex(uint8_t(0));
+    ColorAttachmentIndex nextColorIndex{};
 
     bool needsComma = false;
-    for (ColorAttachmentIndex i : IterateBitSet(value->GetColorAttachmentsMask())) {
+    for (auto i : IterateBitSet(value->GetColorAttachmentsMask())) {
         if (needsComma) {
             s->Append(", ");
         }