Skip to content

Commit

Permalink
rust-analyzer: Set a library's display_name when consolidating crat…
Browse files Browse the repository at this point in the history
…e specs (#1039)

Co-authored-by: Marcel Hlopko <hlopko@google.com>
  • Loading branch information
reiyw and hlopko committed Nov 26, 2021
1 parent cc18aaf commit fe0ffcd
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 3 deletions.
1 change: 1 addition & 0 deletions rust/private/rust_analyzer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ def _create_single_crate(ctx, info):
crate["display_name"] = crate_name
crate["edition"] = info.crate.edition
crate["env"] = {}
crate["crate_type"] = info.crate.type

# Switch on external/ to determine if crates are in the workspace or remote.
# TODO: Some folks may want to override this for vendored dependencies.
Expand Down
3 changes: 3 additions & 0 deletions tools/rust_analyzer/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ rust_library(
rust_test(
name = "gen_rust_project_lib_test",
crate = ":gen_rust_project_lib",
deps = [
"//tools/rust_analyzer/raze:itertools",
],
)

rust_clippy(
Expand Down
132 changes: 129 additions & 3 deletions tools/rust_analyzer/aquery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub struct CrateSpec {
pub cfg: Vec<String>,
pub env: BTreeMap<String, String>,
pub target: String,
pub crate_type: String,
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)]
Expand Down Expand Up @@ -167,6 +168,15 @@ fn consolidate_crate_specs(crate_specs: Vec<CrateSpec>) -> anyhow::Result<BTreeS
log::debug!("{:?}", spec);
if let Some(existing) = consolidated_specs.get_mut(&spec.crate_id) {
existing.deps.extend(spec.deps);

// display_name should match the library's crate name because Rust Analyzer
// seems to use display_name for matching crate entries in rust-project.json
// against symbols in source files. For more details, see
// https://github.com/bazelbuild/rules_rust/issues/1032
if spec.crate_type == "rlib" {
existing.display_name = spec.display_name;
existing.crate_type = "rlib".into();
}
} else {
consolidated_specs.insert(spec.crate_id.clone(), spec);
}
Expand All @@ -178,6 +188,7 @@ fn consolidate_crate_specs(crate_specs: Vec<CrateSpec>) -> anyhow::Result<BTreeS
#[cfg(test)]
mod test {
use super::*;
use itertools::Itertools;

#[test]
fn consolidate_lib_then_test_specs() {
Expand All @@ -194,6 +205,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-extra_test_dep.rs".into(),
Expand All @@ -207,6 +219,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-lib_dep.rs".into(),
Expand All @@ -220,6 +233,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-mylib.rs".into(),
Expand All @@ -233,6 +247,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "bin".into(),
},
];

Expand All @@ -251,6 +266,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-extra_test_dep.rs".into(),
Expand All @@ -264,6 +280,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-lib_dep.rs".into(),
Expand All @@ -277,6 +294,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
])
);
Expand All @@ -297,6 +315,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "bin".into(),
},
CrateSpec {
crate_id: "ID-mylib.rs".into(),
Expand All @@ -310,6 +329,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-extra_test_dep.rs".into(),
Expand All @@ -323,6 +343,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-lib_dep.rs".into(),
Expand All @@ -336,6 +357,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
];

Expand All @@ -344,9 +366,7 @@ mod test {
BTreeSet::from([
CrateSpec {
crate_id: "ID-mylib.rs".into(),
// TODO: It's probably better if the display name matches the library target
// after the specs are consolidated.
display_name: "mylib_test".into(),
display_name: "mylib".into(),
edition: "2018".into(),
root_module: "mylib.rs".into(),
is_workspace_member: true,
Expand All @@ -356,6 +376,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-extra_test_dep.rs".into(),
Expand All @@ -369,6 +390,7 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-lib_dep.rs".into(),
Expand All @@ -382,8 +404,112 @@ mod test {
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
])
);
}

#[test]
fn consolidate_lib_test_main_specs() {
// mylib.rs is a library but has tests and an entry point, and mylib2.rs
// depends on mylib.rs. The display_name of the library target mylib.rs
// should be "mylib" no matter what order the crate specs is in.
// Otherwise Rust Analyzer will not be able to resolve references to
// mylib in mylib2.rs.
let crate_specs = vec![
CrateSpec {
crate_id: "ID-mylib.rs".into(),
display_name: "mylib".into(),
edition: "2018".into(),
root_module: "mylib.rs".into(),
is_workspace_member: true,
deps: BTreeSet::new(),
proc_macro_dylib_path: None,
source: None,
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-mylib.rs".into(),
display_name: "mylib_test".into(),
edition: "2018".into(),
root_module: "mylib.rs".into(),
is_workspace_member: true,
deps: BTreeSet::new(),
proc_macro_dylib_path: None,
source: None,
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "bin".into(),
},
CrateSpec {
crate_id: "ID-mylib.rs".into(),
display_name: "mylib_main".into(),
edition: "2018".into(),
root_module: "mylib.rs".into(),
is_workspace_member: true,
deps: BTreeSet::new(),
proc_macro_dylib_path: None,
source: None,
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "bin".into(),
},
CrateSpec {
crate_id: "ID-mylib2.rs".into(),
display_name: "mylib2".into(),
edition: "2018".into(),
root_module: "mylib2.rs".into(),
is_workspace_member: true,
deps: BTreeSet::from(["ID-mylib.rs".into()]),
proc_macro_dylib_path: None,
source: None,
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
];

for perm in crate_specs.into_iter().permutations(4) {
assert_eq!(
consolidate_crate_specs(perm).unwrap(),
BTreeSet::from([
CrateSpec {
crate_id: "ID-mylib.rs".into(),
display_name: "mylib".into(),
edition: "2018".into(),
root_module: "mylib.rs".into(),
is_workspace_member: true,
deps: BTreeSet::from([]),
proc_macro_dylib_path: None,
source: None,
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
CrateSpec {
crate_id: "ID-mylib2.rs".into(),
display_name: "mylib2".into(),
edition: "2018".into(),
root_module: "mylib2.rs".into(),
is_workspace_member: true,
deps: BTreeSet::from(["ID-mylib.rs".into()]),
proc_macro_dylib_path: None,
source: None,
cfg: vec!["test".into(), "debug_assertions".into()],
env: BTreeMap::new(),
target: "x86_64-unknown-linux-gnu".into(),
crate_type: "rlib".into(),
},
])
);
}
}
}
9 changes: 9 additions & 0 deletions tools/rust_analyzer/raze/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ alias(
],
)

alias(
name = "itertools",
actual = "@rules_rust_tools_rust_analyzer__itertools__0_10_1//:itertools",
tags = [
"cargo-raze",
"manual",
],
)

alias(
name = "log",
actual = "@rules_rust_tools_rust_analyzer__log__0_4_14//:log",
Expand Down
16 changes: 16 additions & 0 deletions tools/rust_analyzer/raze/Cargo.raze.lock
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,19 @@ version = "0.0.0"
dependencies = [
"anyhow",
"env_logger",
"itertools",
"log",
"serde",
"serde_json",
"structopt",
]

[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"

[[package]]
name = "env_logger"
version = "0.9.0"
Expand Down Expand Up @@ -111,6 +118,15 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"

[[package]]
name = "itertools"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]

[[package]]
name = "itoa"
version = "0.4.8"
Expand Down
3 changes: 3 additions & 0 deletions tools/rust_analyzer/raze/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
structopt = "0.3"

[dev-dependencies]
itertools = "0.10"

[package.metadata.raze]
genmode = "Remote"
workspace_path = "//tools/rust_analyzer/raze"
Expand Down
20 changes: 20 additions & 0 deletions tools/rust_analyzer/raze/crates.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ def rules_rust_tools_rust_analyzer_fetch_remote_crates():
build_file = Label("//tools/rust_analyzer/raze/remote:BUILD.clap-2.33.3.bazel"),
)

maybe(
http_archive,
name = "rules_rust_tools_rust_analyzer__either__1_6_1",
url = "https://crates.io/api/v1/crates/either/1.6.1/download",
type = "tar.gz",
sha256 = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457",
strip_prefix = "either-1.6.1",
build_file = Label("//tools/rust_analyzer/raze/remote:BUILD.either-1.6.1.bazel"),
)

maybe(
http_archive,
name = "rules_rust_tools_rust_analyzer__env_logger__0_9_0",
Expand Down Expand Up @@ -121,6 +131,16 @@ def rules_rust_tools_rust_analyzer_fetch_remote_crates():
build_file = Label("//tools/rust_analyzer/raze/remote:BUILD.humantime-2.1.0.bazel"),
)

maybe(
http_archive,
name = "rules_rust_tools_rust_analyzer__itertools__0_10_1",
url = "https://crates.io/api/v1/crates/itertools/0.10.1/download",
type = "tar.gz",
sha256 = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf",
strip_prefix = "itertools-0.10.1",
build_file = Label("//tools/rust_analyzer/raze/remote:BUILD.itertools-0.10.1.bazel"),
)

maybe(
http_archive,
name = "rules_rust_tools_rust_analyzer__itoa__0_4_8",
Expand Down
Loading

0 comments on commit fe0ffcd

Please sign in to comment.