Compiler Unaware of Provided Methods of Trait

353 views Asked by At

I'm using the prost crate in a very "hello world" way, with a basic ProtoBuf file:

foo.proto

syntax = "proto3";
package foo;

message Foo {
    string mystring = 1;
}

I can verify the types that prost produces at compile time by inspecting ./target/PROJECT/build/PROJECT-{some hash}/out/foo.rs:

foo.rs

#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Foo {
    #[prost(string, tag="1")]
    pub mystring: ::prost::alloc::string::String,
}

See that the prost::Message trait gets derived? Its docs claim I have tons of functions at my disposal for this trait, but only the two required ones, encoded_len() and clear(), can be called without error. Any of the provided ones (those with default implementations) result in a cannot find function in this scope error.

main.rs

use prost::Message;

pub mod foo {
    include!(concat!(env!("OUT_DIR"), "/foo.rs"));
}

fn main() {
    let f = foo::Foo { mystring: "bar".to_string() };
    let v = encode_to_vec(&f);
}

cargo run

error[E0425]: cannot find function `encode_to_vec` in this scope
   |
   |     let v = encode_to_vec(&f);
   |             ^^^^^^^^^^^^^ not found in this scope

And, worryingly, this warning implies it's not even looking at the trait it needs to:

warning: unused import: prost::Message

(edit) For reference:

Cargo.toml

[package]
name = "testing"
version = "0.1.0"
edition = "2018"

[dependencies]
prost = { version = "0.7.0", features = ["std"] }

[build-dependencies]
prost-build = "0.7.0"
1

There are 1 answers

3
Caesar On BEST ANSWER

encode_to_vec is not a free function. You need to call it as one of

  • f.encode_to_vec()
  • foo::Foo::encode_to_vec(&f)
  • Message::encode_to_vec(&f)
  • <foo::Foo as Message>::encode_to_vec(&f)

The first method is the most normal, but the other ones may produce useful error messages when you get confused about what's going on.


[Edit:] Well, encode_to_vec was added in prost 0.8.0, so with 0.7.0, it won't be usable.