Add support for the Rust toolchain

To enable Rust build targets in standalone dawn:
- Add `checkout_rust: True` to the gclient `custom_vars` section. As
  it defaults to false:
    "custom_vars": {
      "checkout_rust": True,
    }
- Set `enable_rust = true` in GN args, as it also defaults to false.
- Run gclient sync

Then building `rust_build_tests` will build test targets in
//build/rust/tests, which rely on and verify the functioning of
the Rust toolchain.

Make new rust targets by using the GN templates in //build/rust.

In the chromium build, Rust build targets that use the templates
from //build/rust will just work.

------

Dependent steps that are already done:
1) The //tools/rust repo needs to be created in
   https://bugs.chromium.org/p/chromium/issues/detail?id=1494128
2) Then, we should remove the checkout_tools_rust DEPS var,
3) And update the tools/clang and tools/rust revisions so that they
   are compatible.
4) Roll the chromium //build changes that were required in from
   https://chromium-review.googlesource.com/c/chromium/src/+/4956874
   and
   https://chromium-review.googlesource.com/c/chromium/src/+/4966201
5) The clang roll causes clang-cl to warn on use of offsetof, but it
   does not define __GNUC__, which is used to remove the warning. So
   also remove the warning when __clang__ is defined.

Bug: chromium:1494118
Change-Id: I5e280090ec950a1da9f91e2e4717925ce4b2eaa6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/157120
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: danakj <danakj@chromium.org>
diff --git a/.gitignore b/.gitignore
index 80941cc..b268054 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,7 @@
 /third_party/node-api-headers
 /third_party/partition_alloc
 /third_party/protobuf
+/third_party/rust-toolchain
 /third_party/swiftshader
 /third_party/vulkan-deps
 /third_party/vulkan_memory_allocator
@@ -45,6 +46,7 @@
 /tools/cmake*
 /tools/golang
 /tools/memory
+/tools/rust
 /out
 
 # Tint test validation cache file
diff --git a/.gitmodules b/.gitmodules
index 5db482c..7cfc0f3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -114,3 +114,6 @@
 	path = third_party/partition_alloc
 	url = https://chromium.googlesource.com/chromium/src/base/allocator/partition_allocator.git
 	gclient-condition = dawn_standalone
+[submodule "tools/rust"]
+	path = tools/rust
+	url = https://chromium.googlesource.com/chromium/src/tools/rust
diff --git a/BUILD.gn b/BUILD.gn
index 7493734..c111d1f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -25,6 +25,7 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+import("build/config/rust.gni")
 import("scripts/dawn_overrides_with_defaults.gni")
 import("scripts/tint_overrides_with_defaults.gni")
 
@@ -77,6 +78,13 @@
   ]
 }
 
+if (enable_rust) {
+  group("rust_build_tests") {
+    testonly = true
+    deps = [ "//build/rust/tests" ]
+  }
+}
+
 # This target is built when no specific target is specified on the command line.
 group("default") {
   testonly = true
diff --git a/DEPS b/DEPS
index eec063d..682db69 100644
--- a/DEPS
+++ b/DEPS
@@ -35,6 +35,14 @@
   # Fetch clang-tidy into the same bin/ directory as our clang binary.
   'checkout_clang_tidy': False,
 
+  # Fetch the rust toolchain.
+  #
+  # Use a custom_vars section to enable it:
+  # "custom_vars": {
+  #   "checkout_rust": True,
+  # }
+  'checkout_rust': False,
+
   # Fetch configuration files required for the 'use_remoteexec' gn arg
   'download_remoteexec_cfg': False,
   # RBE instance to use for running remote builds
@@ -53,11 +61,6 @@
 }
 
 deps = {
-  # Dependencies required to use GN/Clang in standalone
-  'build': {
-    'url': '{chromium_git}/chromium/src/build@5885d3c24833ad72845a52a1b913a2b8bc651b56',
-    'condition': 'dawn_standalone',
-  },
   'buildtools': {
     'url': '{chromium_git}/chromium/src/buildtools@a9a6f0c49d0e8fa0cda37337430b4736ab3dc944',
     'condition': 'dawn_standalone',
@@ -101,10 +104,21 @@
     'condition': 'dawn_standalone',
   },
 
-  'tools/clang': {
-    'url': '{chromium_git}/chromium/src/tools/clang@8f75392b4aa947fb55c7c206b36804229595e4da',
+  # Dependencies required to use GN, Clang, and Rust in standalone.
+  # The //build, //tools/clang, and //tools/rust deps should all be updated
+  # in unison, as there are dependencies between them.
+  'build': {
+    'url': '{chromium_git}/chromium/src/build@e2f4d00875f7d00fad39d5af2c6869ac7c7413cc',
     'condition': 'dawn_standalone',
   },
+  'tools/clang': {
+    'url': '{chromium_git}/chromium/src/tools/clang@86aed39db276fb876a2b98c93cc6ff8940377903',
+    'condition': 'dawn_standalone',
+  },
+  'tools/rust': {
+    'url': '{chromium_git}/chromium/src/tools/rust@7052bd3aa0eba2d3d701b7a76219e3b04770540e',
+    'condition': 'dawn_standalone and checkout_rust',
+  },
   'tools/clang/dsymutil': {
     'packages': [{
       'package': 'chromium/llvm-build-tools/dsymutil',
@@ -333,6 +347,12 @@
                '--package=clang-tidy'],
   },
   {
+    'name': 'rust',
+    'pattern': '.',
+    'action': ['python3', 'tools/rust/update_rust.py'],
+    'condition': 'dawn_standalone and checkout_rust',
+  },
+  {
     # Pull rc binaries using checked-in hashes.
     'name': 'rc_win',
     'pattern': '.',
diff --git a/build b/build
index 5885d3c..e2f4d00 160000
--- a/build
+++ b/build
@@ -1 +1 @@
-Subproject commit 5885d3c24833ad72845a52a1b913a2b8bc651b56
+Subproject commit e2f4d00875f7d00fad39d5af2c6869ac7c7413cc
diff --git a/generator/templates/api_cpp.cpp b/generator/templates/api_cpp.cpp
index 4bba53b..e68680e 100644
--- a/generator/templates/api_cpp.cpp
+++ b/generator/templates/api_cpp.cpp
@@ -34,7 +34,7 @@
     #include "{{api}}/{{api}}_cpp.h"
 {% endif %}
 
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
 // error: 'offsetof' within non-standard-layout type '{{metadata.namespace}}::XXX' is conditionally-supported
 #pragma GCC diagnostic ignored "-Winvalid-offsetof"
 #endif
diff --git a/generator/templates/dawn/native/api_structs.cpp b/generator/templates/dawn/native/api_structs.cpp
index 002e17a..bd0f3a3 100644
--- a/generator/templates/dawn/native/api_structs.cpp
+++ b/generator/templates/dawn/native/api_structs.cpp
@@ -34,7 +34,7 @@
 
 #include <tuple>
 
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
 // error: 'offsetof' within non-standard-layout type '{{namespace}}::XXX' is conditionally-supported
 #pragma GCC diagnostic ignored "-Winvalid-offsetof"
 #endif
diff --git a/generator/templates/dawn/wire/WireCmd.cpp b/generator/templates/dawn/wire/WireCmd.cpp
index 52d9602..9e63d7b 100644
--- a/generator/templates/dawn/wire/WireCmd.cpp
+++ b/generator/templates/dawn/wire/WireCmd.cpp
@@ -37,7 +37,7 @@
 #include <cstring>
 #include <limits>
 
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
 // error: 'offsetof' within non-standard-layout type 'wgpu::XXX' is conditionally-supported
 #pragma GCC diagnostic ignored "-Winvalid-offsetof"
 #endif
diff --git a/tools/clang b/tools/clang
index 8f75392..86aed39 160000
--- a/tools/clang
+++ b/tools/clang
@@ -1 +1 @@
-Subproject commit 8f75392b4aa947fb55c7c206b36804229595e4da
+Subproject commit 86aed39db276fb876a2b98c93cc6ff8940377903
diff --git a/tools/rust b/tools/rust
new file mode 160000
index 0000000..7052bd3
--- /dev/null
+++ b/tools/rust
@@ -0,0 +1 @@
+Subproject commit 7052bd3aa0eba2d3d701b7a76219e3b04770540e