rust_project_writer: Support aliased_deps in rust-project.json When generating rust-project.json via `gn gen --export-rust-project`, RustProjectWriter previously emitted only `dep->rust_values().crate_name()` for crate dependencies in `"deps"`, ignoring `target->rust_values().aliased_deps()`. By contrast, NinjaRustBinaryTargetWriter checks `aliased_deps()` when passing `--extern <alias>=<rlib>` flags to `rustc`. When a target uses `aliased_deps` (such as renamed third-party Cargo crates), `rust-analyzer` and Kythe indexers consuming `rust-project.json` could not resolve imports using the aliased name. This change updates `AddTarget` in `rust_project_writer.cc` to check `target->rust_values().aliased_deps()` and emit the aliased dependency name alongside `crate_name()`. Bug:513301934 CONV=1d75e1e8-412c-4982-8ca8-e70282d906f4 Change-Id: I9f90915d1c252aab24c3dcdc7552b115b6ef9779 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/26620 Reviewed-by: Takuto Ikuta <tikuta@google.com> Commit-Queue: Marc Jin <jmarc@google.com>
diff --git a/src/gn/rust_project_writer.cc b/src/gn/rust_project_writer.cc index 17e92d4..69c93e6 100644 --- a/src/gn/rust_project_writer.cc +++ b/src/gn/rust_project_writer.cc
@@ -280,9 +280,14 @@ } // Add the rest of the crate dependencies. + const auto& aliased_deps = target->rust_values().aliased_deps(); for (const auto& dep : crate_deps) { auto idx = lookup[dep]; - crate.AddDependency(idx, dep->rust_values().crate_name()); + std::string_view crate_name = dep->rust_values().crate_name(); + if (auto it = aliased_deps.find(dep->label()); it != aliased_deps.end()) { + crate_name = it->second; + } + crate.AddDependency(idx, std::string(crate_name)); } crate_list.push_back(crate);
diff --git a/src/gn/rust_project_writer_unittest.cc b/src/gn/rust_project_writer_unittest.cc index d48a879..5532a72 100644 --- a/src/gn/rust_project_writer_unittest.cc +++ b/src/gn/rust_project_writer_unittest.cc
@@ -699,3 +699,88 @@ ExpectEqOrShowDiff(expected_json, out); } + +TEST_F(RustProjectJSONWriter, RustTargetAliasedDep) { + Err err; + TestWithScope setup; + + Target dep(setup.settings(), Label(SourceDir("//tortoise/"), "bar")); + dep.set_output_type(Target::RUST_LIBRARY); + dep.visibility().SetPublic(); + SourceFile tlib("//tortoise/lib.rs"); + dep.sources().push_back(tlib); + dep.source_types_used().Set(SourceFile::SOURCE_RS); + dep.rust_values().set_crate_root(tlib); + dep.rust_values().crate_name() = "tortoise_mangled_hash"; + dep.SetToolchain(setup.toolchain()); + ASSERT_TRUE(dep.OnResolved(&err)); + + Target target(setup.settings(), Label(SourceDir("//hare/"), "bar")); + target.set_output_type(Target::RUST_LIBRARY); + target.visibility().SetPublic(); + SourceFile harelib("//hare/lib.rs"); + target.sources().push_back(harelib); + target.source_types_used().Set(SourceFile::SOURCE_RS); + target.rust_values().set_crate_root(harelib); + target.rust_values().crate_name() = "hare"; + target.rust_values().aliased_deps()[dep.label()] = "tortoise_alias"; + target.public_deps().push_back(LabelTargetPair(&dep)); + target.SetToolchain(setup.toolchain()); + ASSERT_TRUE(target.OnResolved(&err)); + + std::ostringstream stream; + std::vector<const Target*> targets; + targets.push_back(&target); + RustProjectWriter::RenderJSON(setup.build_settings(), targets, stream); + std::string out = stream.str(); +#if defined(OS_WIN) + base::ReplaceSubstringsAfterOffset(&out, 0, "\r\n", "\n"); +#endif + const char expected_json[] = R"({ + "crates": [ + { + "crate_id": 0, + "root_module": "tortoise/lib.rs", + "label": "//tortoise:bar", + "source": { + "include_dirs": [ + "tortoise/" + ], + "exclude_dirs": [] + }, + "deps": [ + ], + "edition": "2015", + "cfg": [ + "test", + "debug_assertions" + ] + }, + { + "crate_id": 1, + "root_module": "hare/lib.rs", + "label": "//hare:bar", + "source": { + "include_dirs": [ + "hare/" + ], + "exclude_dirs": [] + }, + "deps": [ + { + "crate": 0, + "name": "tortoise_alias" + } + ], + "edition": "2015", + "cfg": [ + "test", + "debug_assertions" + ] + } + ] +} +)"; + + ExpectEqOrShowDiff(expected_json, out); +}