Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "rust_analyzer: don't build a tree of RustAnalyzerInfos (#3028)" #3093

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions extensions/prost/private/prost.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,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 @@ -352,10 +349,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
Loading