Skip to content

Commit

Permalink
Revert "rust_analyzer: don't build a tree of RustAnalyzerInfos (#3028)…
Browse files Browse the repository at this point in the history
…" (#3093)

This reverts commit 443b089
(#3028).
  • Loading branch information
UebelAndre authored Dec 16, 2024
1 parent f7be79c commit 4652fb5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 46 deletions.
10 changes: 2 additions & 8 deletions extensions/prost/private/prost.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -299,15 +299,12 @@ def _rust_prost_aspect_impl(target, ctx):
# https://github.com/rust-analyzer/rust-analyzer/blob/2021-11-15/crates/project_model/src/workspace.rs#L529-L531
cfgs = ["test", "debug_assertions"]

crate_id = "prost-" + dep_variant_info.crate_info.root.path

rust_analyzer_info = write_rust_analyzer_spec_file(ctx, ctx.rule.attr, ctx.label, RustAnalyzerInfo(
id = crate_id,
aliases = {},
crate = dep_variant_info.crate_info,
cfgs = cfgs,
env = dep_variant_info.crate_info.rustc_env,
deps = depset([dep.id for dep in rust_analyzer_deps]).to_list(),
deps = rust_analyzer_deps,
crate_specs = depset(transitive = [dep.crate_specs for dep in rust_analyzer_deps]),
proc_macro_dylib_path = None,
build_info = dep_variant_info.build_info,
Expand Down Expand Up @@ -390,10 +387,7 @@ def _rust_prost_library_impl(ctx):
rust_generated_srcs = rust_generated_srcs,
proto_descriptor_set = proto_descriptor_set,
),
RustAnalyzerGroupInfo(
crate_specs = proto_dep[RustAnalyzerInfo].crate_specs,
deps = proto_dep[RustAnalyzerInfo].deps,
),
RustAnalyzerGroupInfo(deps = [proto_dep[RustAnalyzerInfo]]),
]

rust_prost_library = rule(
Expand Down
8 changes: 3 additions & 5 deletions rust/private/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -157,22 +157,20 @@ TestCrateInfo = provider(
RustAnalyzerInfo = provider(
doc = "RustAnalyzerInfo holds rust crate metadata for targets",
fields = {
"aliases": "Dict[String, String]: Maps crate IDs to Replacement names these targets should be known as in Rust code",
"aliases": "Dict[RustAnalyzerInfo, String]: Replacement names these targets should be known as in Rust code",
"build_info": "BuildInfo: build info for this crate if present",
"cfgs": "List[String]: features or other compilation `--cfg` settings",
"crate": "CrateInfo: Crate information.",
"crate_specs": "Depset[File]: transitive closure of OutputGroupInfo files",
"deps": "List[String]: IDs of direct dependency crates",
"deps": "List[RustAnalyzerInfo]: direct dependencies",
"env": "Dict[String: String]: Environment variables, used for the `env!` macro",
"id": "String: Arbitrary unique ID for this crate",
"proc_macro_dylib_path": "File: compiled shared library output of proc-macro rule",
},
)

RustAnalyzerGroupInfo = provider(
doc = "RustAnalyzerGroupInfo holds multiple RustAnalyzerInfos",
fields = {
"crate_specs": "Depset[File]: transitive closure of OutputGroupInfo files",
"deps": "List[String]: crate IDs of direct dependencies",
"deps": "List[RustAnalyzerInfo]: direct dependencies",
},
)
75 changes: 42 additions & 33 deletions rust/private/rust_analyzer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ def write_rust_analyzer_spec_file(ctx, attrs, owner, base_info):
cfgs = base_info.cfgs,
env = base_info.env,
deps = base_info.deps,
id = base_info.id,
crate_specs = depset(direct = [crate_spec], transitive = [base_info.crate_specs]),
proc_macro_dylib_path = base_info.proc_macro_dylib_path,
build_info = base_info.build_info,
Expand All @@ -73,6 +72,21 @@ def write_rust_analyzer_spec_file(ctx, attrs, owner, base_info):

return rust_analyzer_info

def _accumulate_rust_analyzer_info(dep_infos_to_accumulate, label_index_to_accumulate, dep):
if dep == None:
return
if RustAnalyzerInfo in dep:
label_index_to_accumulate[dep.label] = dep[RustAnalyzerInfo]
dep_infos_to_accumulate.append(dep[RustAnalyzerInfo])
if RustAnalyzerGroupInfo in dep:
for expanded_dep in dep[RustAnalyzerGroupInfo].deps:
label_index_to_accumulate[expanded_dep.crate.owner] = expanded_dep
dep_infos_to_accumulate.append(expanded_dep)

def _accumulate_rust_analyzer_infos(dep_infos_to_accumulate, label_index_to_accumulate, deps_attr):
for dep in deps_attr:
_accumulate_rust_analyzer_info(dep_infos_to_accumulate, label_index_to_accumulate, dep)

def _rust_analyzer_aspect_impl(target, ctx):
if (rust_common.crate_info not in target and
rust_common.test_crate_info not in target and
Expand All @@ -93,55 +107,41 @@ def _rust_analyzer_aspect_impl(target, ctx):
cfgs += [f[6:] for f in ctx.rule.attr.rustc_flags if f.startswith("--cfg ") or f.startswith("--cfg=")]

build_info = None
dep_infos = []
labels_to_rais = {}

for dep in getattr(ctx.rule.attr, "deps", []):
# Save BuildInfo if we find any (for build script output)
if BuildInfo in dep:
build_info = dep[BuildInfo]

# Gather required info from dependencies.
label_to_id = {} # {Label of dependency => crate_id}
crate_specs = [] # [depset of File - transitive crate_spec.json files]
attrs = ctx.rule.attr
all_deps = getattr(attrs, "deps", []) + getattr(attrs, "proc_macro_deps", []) + \
[dep for dep in [getattr(attrs, "crate", None), getattr(attrs, "actual", None)] if dep != None]
for dep in all_deps:
if RustAnalyzerInfo in dep:
label_to_id[dep.label] = dep[RustAnalyzerInfo].id
crate_specs.append(dep[RustAnalyzerInfo].crate_specs)
if RustAnalyzerGroupInfo in dep:
for expanded_dep in dep[RustAnalyzerGroupInfo].deps:
label_to_id[expanded_dep] = expanded_dep
crate_specs.append(dep[RustAnalyzerGroupInfo].crate_specs)

deps = label_to_id.values()
crate_specs = depset(transitive = crate_specs)
_accumulate_rust_analyzer_infos(dep_infos, labels_to_rais, getattr(ctx.rule.attr, "deps", []))
_accumulate_rust_analyzer_infos(dep_infos, labels_to_rais, getattr(ctx.rule.attr, "proc_macro_deps", []))

_accumulate_rust_analyzer_info(dep_infos, labels_to_rais, getattr(ctx.rule.attr, "crate", None))
_accumulate_rust_analyzer_info(dep_infos, labels_to_rais, getattr(ctx.rule.attr, "actual", None))

if rust_common.crate_group_info in target:
return [RustAnalyzerGroupInfo(deps = deps, crate_specs = crate_specs)]
return [RustAnalyzerGroupInfo(deps = dep_infos)]
elif rust_common.crate_info in target:
crate_info = target[rust_common.crate_info]
elif rust_common.test_crate_info in target:
crate_info = target[rust_common.test_crate_info].crate
else:
fail("Unexpected target type: {}".format(target))

aliases = {
label_to_id[target.label]: name
for (target, name) in getattr(attrs, "aliases", {}).items()
if target.label in label_to_id
}

# An arbitrary unique and stable identifier.
crate_id = "ID-" + crate_info.root.path
aliases = {}
for aliased_target, aliased_name in getattr(ctx.rule.attr, "aliases", {}).items():
if aliased_target.label in labels_to_rais:
aliases[labels_to_rais[aliased_target.label]] = aliased_name

rust_analyzer_info = write_rust_analyzer_spec_file(ctx, ctx.rule.attr, ctx.label, RustAnalyzerInfo(
id = crate_id,
aliases = aliases,
crate = crate_info,
cfgs = cfgs,
env = crate_info.rustc_env,
deps = deps,
crate_specs = crate_specs,
deps = dep_infos,
crate_specs = depset(transitive = [dep.crate_specs for dep in dep_infos]),
proc_macro_dylib_path = find_proc_macro_dylib_path(toolchain, target),
build_info = build_info,
))
Expand Down Expand Up @@ -193,6 +193,14 @@ _WORKSPACE_TEMPLATE = "__WORKSPACE__/"
_EXEC_ROOT_TEMPLATE = "__EXEC_ROOT__/"
_OUTPUT_BASE_TEMPLATE = "__OUTPUT_BASE__/"

def _crate_id(crate_info):
"""Returns a unique stable identifier for a crate
Returns:
(string): This crate's unique stable id.
"""
return "ID-" + crate_info.root.path

def _create_single_crate(ctx, attrs, info):
"""Creates a crate in the rust-project.json format.
Expand All @@ -206,7 +214,8 @@ def _create_single_crate(ctx, attrs, info):
"""
crate_name = info.crate.name
crate = dict()
crate["crate_id"] = info.id
crate_id = _crate_id(info.crate)
crate["crate_id"] = crate_id
crate["display_name"] = crate_name
crate["edition"] = info.crate.edition
crate["env"] = {}
Expand Down Expand Up @@ -254,8 +263,8 @@ def _create_single_crate(ctx, attrs, info):
# There's one exception - if the dependency is the same crate name as the
# the crate being processed, we don't add it as a dependency to itself. This is
# common and expected - `rust_test.crate` pointing to the `rust_library`.
crate["deps"] = [id for id in info.deps if id != info.id]
crate["aliases"] = info.aliases
crate["deps"] = [_crate_id(dep.crate) for dep in info.deps if _crate_id(dep.crate) != crate_id]
crate["aliases"] = {_crate_id(alias_target.crate): alias_name for alias_target, alias_name in info.aliases.items()}
crate["cfg"] = info.cfgs
toolchain = find_toolchain(ctx)
crate["target"] = (_EXEC_ROOT_TEMPLATE + toolchain.target_json.path) if toolchain.target_json else toolchain.target_flag_value
Expand Down

0 comments on commit 4652fb5

Please sign in to comment.