bazelbuild / bazelbuild/rules_rust

Protos that share `package` can't be merged in a `rust_prost_library`?

Open
#3,471 0 comments 0 reactions 0 assignees View on GitHub
needs-triage
Dominant language
Starlark
Stars
843
Forks
651
Avg merge
2d 18h
Merged PRs (30d)
15

Description

There are some cases where there are multiple protos that share a `package`:

```proto
// src/bar/fpga/foo/hal/foo_hal.proto
package bar.foo.hal;

message Hal {
...
}
```

```proto
// src/bar/fpga/foo/hal/foo_io_trace.proto
package bar.foo.hal;

message IoRequest {
...
}
```

AIUI, the canonical way to handle this from a `proto_library` perspective is via an alias-library. However, that's currently broken (#2808).

My workaround was to make a single `proto_library` target with multiple sources:

```starlark
proto_library(
name = "foo_hal_unified_proto",
srcs = [
"//src/bar/fpga/foo/hal/foo_hal.proto",
"//src/bar/fpga/foo/hal/foo_io_trace.proto",
],
...
)
```

And create a single `rust_prost_library` that references it:

```
rust_prost_library(
name = "foo_hal_unified_rust_proto",
proto = ":foo_hal_unified_proto",
)
```

However, when code eventually consumes that `rust_prost_library`, it looks like rust is getting confused about some mismatched types:

```rust
error[E0308]: mismatched types
--> rust/qh-ecs/src/mmio/mod.rs:92:27
|
92 | request: Some(self.request.to_proto()),
| ---- ^^^^^^^^^^^^^^^^^^^^^^^ expected `IoRequest`, found a different `IoRequest`
| |
| arguments to this enum variant are incorrect
|
= note: `IoRequest` and `IoRequest` have similar names, but are actually distinct types
note: `IoRequest` is defined in crate `foo_hal_unified_proto`
--> bazel-out/k8-fastbuild/bin/src/bar/fpga/foo/hal/foo_hal_unified_proto.lib.rs:220:13
note: `IoRequest` is defined in crate `foo_io_trace_proto`
--> bazel-out/k8-fastbuild/bin/src/bar/fpga/foo/hal/foo_io_trace_proto.lib.rs:20:13
help: the type constructed contains `qh_proto::bar::foo::hal::IoRequest` due to the type of the argument passed
--> rust/qh-ecs/src/mmio/mod.rs:92:22
|
92 | request: Some(self.request.to_proto()),
| ^^^^^-----------------------^
| |
| this argument influences the type of `Some`
note: tuple variant defined here
--> /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/option.rs:580:5
```

and later on I get a similar complaint about the other member of the pair:

```rust
note: `qh_proto::bar::foo::hal::Hal` is defined in crate `foo_hal_unified_proto`
--> bazel-out/k8-fastbuild/bin/src/bar/fpga/foo/hal/foo_hal_unified_proto.lib.rs:159:13
note: `Hal` is defined in crate `foo_hal_proto`
--> bazel-out/k8-fastbuild/bin/src/bar/fpga/foo/hal/foo_hal_proto.lib.rs:159:13
```

What's really strange is that the `proto_library`s `foo_io_trace_proto` and `foo_hal_proto` _don't have an associated `rust_prost_library` target_ aside from the unified one, so how are those `foo_io_trace_proto.lib.rs` and `foo_hal_proto.lib.rs` files getting ma#3464

### Other notes:

+ I don't control these protos, so it's not really possible to merge them at the proto level.
+ In order to reduce the diff of migrating our rust to bazel, I'm re-exporting the protos in the `qh-proto` namespace like so:
```rust
// rust/qh-proto/src/lib.rs
pub mod bar {
pub use foo_hal_unified_proto::bar::foo as foo; // `use qh_proto::bar::foo`
}
```
+ Building the protos outside of bazel via `prost` and `protoc` results in `bar.foo.hal.rs` that merges the two protos and looks like:
```rust
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Hal {
#[prost(message, optional, tag = "1")]
pub global_csr: ::core::option::Option,
...
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct IoRequest {
#[prost(message, optional, tag = "1")]
pub timestamp: ::core::option::Option<::prost_types::Timestamp>,
...,
}
/// Nested message and enum types in `IoRequest`.
pub mod io_request {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum Transaction {
...,
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.