[tint][utils] Fix diagnostic initializer_list ctor

This wasn't correctly initializing the error count.
Also add a constructor from a VectorRef.

Change-Id: I9b9f5e478e877d6edc14292682a9e7edc295d249
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162402
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/utils/diagnostic/diagnostic.cc b/src/tint/utils/diagnostic/diagnostic.cc
index 8a51ac9..ff0170c 100644
--- a/src/tint/utils/diagnostic/diagnostic.cc
+++ b/src/tint/utils/diagnostic/diagnostic.cc
@@ -33,13 +33,29 @@
 
 namespace tint::diag {
 
+namespace {
+size_t CountErrors(VectorRef<Diagnostic> diags) {
+    size_t count = 0;
+    for (auto& diag : diags) {
+        if (diag.severity >= Severity::Error) {
+            count++;
+        }
+    }
+    return count;
+}
+}  // namespace
+
 Diagnostic::Diagnostic() = default;
 Diagnostic::Diagnostic(const Diagnostic&) = default;
 Diagnostic::~Diagnostic() = default;
 Diagnostic& Diagnostic::operator=(const Diagnostic&) = default;
 
 List::List() = default;
-List::List(std::initializer_list<Diagnostic> list) : entries_(list) {}
+List::List(std::initializer_list<Diagnostic> list)
+    : entries_(list), error_count_(CountErrors(entries_)) {}
+List::List(VectorRef<Diagnostic> list)
+    : entries_(std::move(list)), error_count_(CountErrors(entries_)) {}
+
 List::List(const List& rhs) = default;
 
 List::List(List&& rhs) = default;
diff --git a/src/tint/utils/diagnostic/diagnostic.h b/src/tint/utils/diagnostic/diagnostic.h
index 03c0705..a077f47 100644
--- a/src/tint/utils/diagnostic/diagnostic.h
+++ b/src/tint/utils/diagnostic/diagnostic.h
@@ -108,28 +108,31 @@
     /// Constructs the list with no elements.
     List();
 
-    /// Copy constructor. Copies the diagnostics from `list` into this list.
+    /// Constructor. Copies the diagnostics from @p list into this list.
     /// @param list the list of diagnostics to copy into this list.
     List(std::initializer_list<Diagnostic> list);
 
-    /// Copy constructor. Copies the diagnostics from `list` into this list.
+    /// Constructor. Copies the diagnostics from @p list into this list.
+    /// @param list the list of diagnostics to copy into this list.
+    explicit List(VectorRef<Diagnostic> list);
+
+    /// Copy constructor. Copies the diagnostics from @p list into this list.
     /// @param list the list of diagnostics to copy into this list.
     List(const List& list);
 
-    /// Move constructor. Moves the diagnostics from `list` into this list.
+    /// Move constructor. Moves the diagnostics from @p list into this list.
     /// @param list the list of diagnostics to move into this list.
     List(List&& list);
 
     /// Destructor
     ~List();
 
-    /// Assignment operator. Copies the diagnostics from `list` into this list.
+    /// Assignment operator. Copies the diagnostics from @p list into this list.
     /// @param list the list to copy into this list.
     /// @return this list.
     List& operator=(const List& list);
 
-    /// Assignment move operator. Moves the diagnostics from `list` into this
-    /// list.
+    /// Assignment move operator. Moves the diagnostics from @p list into this list.
     /// @param list the list to move into this list.
     /// @return this list.
     List& operator=(List&& list);
diff --git a/src/tint/utils/diagnostic/diagnostic_test.cc b/src/tint/utils/diagnostic/diagnostic_test.cc
index a27798e..f947b62 100644
--- a/src/tint/utils/diagnostic/diagnostic_test.cc
+++ b/src/tint/utils/diagnostic/diagnostic_test.cc
@@ -33,12 +33,28 @@
 namespace tint::diag {
 namespace {
 
+TEST(DiagListTest, CtorInitializerList) {
+    Diagnostic err_a, err_b;
+    err_a.severity = Severity::Error;
+    err_b.severity = Severity::Fatal;
+    List list{err_a, err_b};
+    EXPECT_EQ(list.count(), 2u);
+}
+
+TEST(DiagListTest, CtorVectorRef) {
+    Diagnostic err_a, err_b;
+    err_a.severity = Severity::Error;
+    err_b.severity = Severity::Fatal;
+    List list(Vector{err_a, err_b});
+    EXPECT_EQ(list.count(), 2u);
+}
+
 TEST(DiagListTest, OwnedFilesShared) {
     auto file = std::make_shared<Source::File>("path", "content");
 
-    diag::List list_a, list_b;
+    List list_a, list_b;
     {
-        diag::Diagnostic diag{};
+        Diagnostic diag{};
         diag.source = Source{Source::Range{{0, 0}}, file.get()};
         list_a.add(std::move(diag));
     }