[tint] Mark operator bool() as explicit

Helps prevent accidental bool coercion to an integer type.

Change-Id: I21010abf4975c9cb94e58be62788c4ae03cbca85
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/189708
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/hlsl/writer/ast_raise/decompose_memory_access.cc b/src/tint/lang/hlsl/writer/ast_raise/decompose_memory_access.cc
index 0b2500a..bacc9a0 100644
--- a/src/tint/lang/hlsl/writer/ast_raise/decompose_memory_access.cc
+++ b/src/tint/lang/hlsl/writer/ast_raise/decompose_memory_access.cc
@@ -321,10 +321,10 @@
 
 /// BufferAccess describes a single storage or uniform buffer access
 struct BufferAccess {
-    sem::GlobalVariable const* var = nullptr;  // Storage or uniform buffer variable
-    Offset const* offset = nullptr;            // The byte offset on var
-    core::type::Type const* type = nullptr;    // The type of the access
-    operator bool() const { return var; }      // Returns true if valid
+    sem::GlobalVariable const* var = nullptr;       // Storage or uniform buffer variable
+    Offset const* offset = nullptr;                 // The byte offset on var
+    core::type::Type const* type = nullptr;         // The type of the access
+    explicit operator bool() const { return var; }  // Returns true if valid
 };
 
 /// Store describes a single storage or uniform buffer write
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser.h b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
index 8f755f7..106221a 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
@@ -103,7 +103,7 @@
     TypedExpression& operator=(const TypedExpression&);
 
     /// @returns true if both type and expr are not nullptr
-    operator bool() const { return type && expr; }
+    explicit operator bool() const { return type && expr; }
 
     /// The type
     const Type* type = nullptr;
diff --git a/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc b/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc
index 0dbbc5b..72efe20 100644
--- a/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/lang/wgsl/ast/transform/zero_init_workgroup_memory.cc
@@ -119,7 +119,7 @@
         ArrayIndices array_indices;
 
         /// @returns true if the expr is not null (null usually indicates a failure)
-        operator bool() const { return expr != nullptr; }
+        explicit operator bool() const { return expr != nullptr; }
     };
 
     /// Statement holds information about a statement that will zero workgroup
diff --git a/src/tint/lang/wgsl/helpers/append_vector.cc b/src/tint/lang/wgsl/helpers/append_vector.cc
index dab1506..8ea2ebd 100644
--- a/src/tint/lang/wgsl/helpers/append_vector.cc
+++ b/src/tint/lang/wgsl/helpers/append_vector.cc
@@ -45,7 +45,7 @@
 struct VectorConstructorInfo {
     const sem::Call* call = nullptr;
     const sem::ValueConstructor* ctor = nullptr;
-    operator bool() const { return call != nullptr; }
+    explicit operator bool() const { return call != nullptr; }
 };
 VectorConstructorInfo AsVectorConstructor(const sem::ValueExpression* expr) {
     if (auto* call = expr->As<sem::Call>()) {
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
index b404397..7243f25 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
@@ -1069,9 +1069,7 @@
     /// name.
     void Bind(const core::ir::Value* value, Symbol name) {
         TINT_ASSERT(value);
-
-        bool added = bindings_.Add(value, VariableValue{name});
-        if (TINT_UNLIKELY(!added)) {
+        if (TINT_UNLIKELY(!bindings_.Add(value, VariableValue{name}))) {
             TINT_ICE() << "Bind(" << value->TypeInfo().name << ") called twice for same value";
         }
     }
diff --git a/src/tint/utils/command/command_posix.cc b/src/tint/utils/command/command_posix.cc
index f3c30de..fae21be 100644
--- a/src/tint/utils/command/command_posix.cc
+++ b/src/tint/utils/command/command_posix.cc
@@ -75,7 +75,7 @@
     operator int() { return handle_; }
 
     /// @returns true if the file is not closed
-    operator bool() { return handle_ != kClosed; }
+    explicit operator bool() { return handle_ != kClosed; }
 
   private:
     File(const File&) = delete;
@@ -103,7 +103,7 @@
     }
 
     /// @returns true if the pipe has an open read or write file
-    operator bool() { return read || write; }
+    explicit operator bool() { return read || write; }
 
     /// The reader end of the pipe
     File read;
diff --git a/src/tint/utils/command/command_windows.cc b/src/tint/utils/command/command_windows.cc
index a6a577b..e591416 100644
--- a/src/tint/utils/command/command_windows.cc
+++ b/src/tint/utils/command/command_windows.cc
@@ -73,7 +73,7 @@
     operator HANDLE() { return handle_; }
 
     /// @returns true if the handle is not invalid
-    operator bool() { return handle_ != nullptr; }
+    explicit operator bool() { return handle_ != nullptr; }
 
   private:
     Handle(const Handle&) = delete;
@@ -106,7 +106,7 @@
     }
 
     /// @returns true if the pipe has an open read or write file
-    operator bool() { return read || write; }
+    explicit operator bool() { return read || write; }
 
     /// The reader end of the pipe
     Handle read;
diff --git a/src/tint/utils/containers/hashmap.h b/src/tint/utils/containers/hashmap.h
index 69790f3..df1ed08 100644
--- a/src/tint/utils/containers/hashmap.h
+++ b/src/tint/utils/containers/hashmap.h
@@ -90,7 +90,7 @@
     T* value = nullptr;
 
     /// @returns `true` if #value is not null.
-    operator bool() const { return value; }
+    explicit operator bool() const { return value; }
 
     /// @returns the dereferenced value, which must not be null.
     T& operator*() const { return *value; }
@@ -129,7 +129,7 @@
     bool added = false;
 
     /// @returns #added
-    operator bool() const { return added; }
+    explicit operator bool() const { return added; }
 };
 
 /// An unordered hashmap, with a fixed-size capacity that avoids heap allocations.
diff --git a/src/tint/utils/containers/hashmap_test.cc b/src/tint/utils/containers/hashmap_test.cc
index af926a2..f3b91bd 100644
--- a/src/tint/utils/containers/hashmap_test.cc
+++ b/src/tint/utils/containers/hashmap_test.cc
@@ -421,7 +421,7 @@
         switch (rnd() % 7) {
             case 0: {  // Add
                 auto expected = reference.emplace(key, value).second;
-                EXPECT_EQ(map.Add(key, value), expected) << "i:" << i;
+                EXPECT_EQ(map.Add(key, value).added, expected) << "i:" << i;
                 EXPECT_EQ(map.Get(key), value) << "i:" << i;
                 EXPECT_TRUE(map.Contains(key)) << "i:" << i;
                 break;
diff --git a/src/tint/utils/file/tmpfile.h b/src/tint/utils/file/tmpfile.h
index 0ae8e95..6bcd663 100644
--- a/src/tint/utils/file/tmpfile.h
+++ b/src/tint/utils/file/tmpfile.h
@@ -50,7 +50,7 @@
     ~TmpFile();
 
     /// @return true if the temporary file was successfully created.
-    operator bool() { return !path_.empty(); }
+    explicit operator bool() { return !path_.empty(); }
 
     /// @return the path to the temporary file
     std::string Path() const { return path_; }
diff --git a/src/tint/utils/id/generation_id.h b/src/tint/utils/id/generation_id.h
index 018b4a2..b3078df 100644
--- a/src/tint/utils/id/generation_id.h
+++ b/src/tint/utils/id/generation_id.h
@@ -67,7 +67,7 @@
     uint32_t Value() const { return val; }
 
     /// @returns true if this GenerationID is valid
-    operator bool() const { return val != 0; }
+    explicit operator bool() const { return val != 0; }
 
   private:
     explicit GenerationID(uint32_t);
diff --git a/src/tint/utils/symbol/symbol.h b/src/tint/utils/symbol/symbol.h
index 9f26bb0..10b7bd7 100644
--- a/src/tint/utils/symbol/symbol.h
+++ b/src/tint/utils/symbol/symbol.h
@@ -83,7 +83,7 @@
     bool IsValid() const { return val_ != static_cast<uint32_t>(-1); }
 
     /// @returns true if the symbol is valid
-    operator bool() const { return IsValid(); }
+    explicit operator bool() const { return IsValid(); }
 
     /// @returns the value for the symbol
     uint32_t value() const { return val_; }