[rust] Add sysroot_src to rust-project.json

This was changed to being required recently:

> `sysroot_src` is required now if you want to have the sysroot
> source libraries be loaded. I think we used to infer it as
> `{sysroot}/lib/rustlib/src/rust/library` before when only the
> `sysroot` field was given but that was since changed to make it
> possible in having a sysroot without the standard library sources
> (that is only have the binaries available). So if you want the
> library sources to be loaded by rust-analyzer you will have to set
> that field as well now.

From
https://github.com/Rust-for-Linux/linux/commit/ce5693f192f10a9180c76fae767890e87273ab78.

Change-Id: Iaff1544c98d5dd5db1824d2824f3be01087528fe
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/17680
Commit-Queue: Tyler Mandry <tmandry@google.com>
Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/rust_project_writer.cc b/src/gn/rust_project_writer.cc
index 8bcd495..a77c3f1 100644
--- a/src/gn/rust_project_writer.cc
+++ b/src/gn/rust_project_writer.cc
@@ -258,8 +258,17 @@
   if (sysroot.has_value()) {
     base::FilePath rebased_out_dir =
         build_settings->GetFullPath(build_settings->build_dir());
-    auto sysroot_path = FilePathToUTF8(rebased_out_dir) + sysroot.value();
-    rust_project << "  \"sysroot\": \"" << sysroot_path << "\"," NEWLINE;
+    base::FilePath sysroot_path =
+        rebased_out_dir.Append(UTF8ToFilePath(sysroot.value()));
+    base::FilePath sysroot_src_path = sysroot_path.AppendASCII("lib")
+                                          .AppendASCII("rustlib")
+                                          .AppendASCII("src")
+                                          .AppendASCII("rust")
+                                          .AppendASCII("library");
+    std::string sysroot_dir = FilePathToUTF8(sysroot_path);
+    std::string sysroot_src_dir = FilePathToUTF8(sysroot_src_path);
+    rust_project << "  \"sysroot\": \"" << sysroot_dir << "\"," NEWLINE;
+    rust_project << "  \"sysroot_src\": \"" << sysroot_src_dir << "\"," NEWLINE;
   }
 
   rust_project << "  \"crates\": [";
diff --git a/src/gn/rust_project_writer_helpers_unittest.cc b/src/gn/rust_project_writer_helpers_unittest.cc
index 14d5c35..7ef39e2 100644
--- a/src/gn/rust_project_writer_helpers_unittest.cc
+++ b/src/gn/rust_project_writer_helpers_unittest.cc
@@ -110,7 +110,15 @@
 
   const char expected_json[] =
       "{\n"
+#if defined(OS_WIN)
+      "  \"sysroot\": \"/root/out/Debug\\sysroot\",\n"
+      "  \"sysroot_src\": "
+      "\"/root/out/Debug\\sysroot\\lib\\rustlib\\src\\rust\\library\",\n"
+#else
       "  \"sysroot\": \"/root/out/Debug/sysroot\",\n"
+      "  \"sysroot_src\": "
+      "\"/root/out/Debug/sysroot/lib/rustlib/src/rust/library\",\n"
+#endif
       "  \"crates\": [\n"
       "  ]\n"
       "}\n";
@@ -248,4 +256,4 @@
   std::vector<std::string> expected = {"feature=\"foo_enabled\"",
                                        "feature=\"bar_enabled\""};
   EXPECT_EQ(expected, result);
-}
\ No newline at end of file
+}