capnproto / capnpc-rust

Cap'n Proto code generation for Rust
75 stars 26 forks source link

Trouble accessing from non-top level? #5

Closed Hoverbear closed 6 years ago

Hoverbear commented 9 years ago

Was playing with this and had the following file structure:

├── Cargo.lock
├── Cargo.toml
├── src
│   ├── main.rs
│   └── schema
│       ├── person.capnp
│       └── person_capnp.rs

Where person_capnp.rs is generated via capnp compile -o rust src/schema/*.capnp.

I was hoping to include a schema/mod.rs which re-exported the person in person_capnp.rs.

schema/mod.rs:

mod person_capnp {
    include!("./person_capnp.rs");
}

main.rs:

#![feature(path)]

extern crate capnp;
extern crate capnpc;

mod schema;

fn main() {

}

Results in this error:

➜  capntest git:(master) ✗ cargo build
   Compiling capntest v0.0.1 (file:///Users/hoverbear/git/capntest)
src/schema/person_capnp.rs:60:55: 60:67 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:60     pub fn get_phones(self) -> struct_list::Reader<'a,::person_capnp::person::phone_number::Reader<'a>> {
                                                                                    ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:60:55: 60:103 error: use of undeclared type name `person_capnp::person::phone_number::Reader`
src/schema/person_capnp.rs:60     pub fn get_phones(self) -> struct_list::Reader<'a,::person_capnp::person::phone_number::Reader<'a>> {
                                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:67:35: 67:47 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:67     pub fn get_birthdate(self) -> ::person_capnp::date::Reader<'a> {
                                                                ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:67:35: 67:67 error: use of undeclared type name `person_capnp::date::Reader`
src/schema/person_capnp.rs:67     pub fn get_birthdate(self) -> ::person_capnp::date::Reader<'a> {
                                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:149:56: 149:68 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:149     pub fn get_phones(self) -> struct_list::Builder<'a,::person_capnp::person::phone_number::Builder<'a>> {
                                                                                      ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:149:56: 149:105 error: use of undeclared type name `person_capnp::person::phone_number::Builder`
src/schema/person_capnp.rs:149     pub fn get_phones(self) -> struct_list::Builder<'a,::person_capnp::person::phone_number::Builder<'a>> {
                                                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:153:65: 153:77 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:153     pub fn set_phones(&mut self, value : struct_list::Reader<'a,::person_capnp::person::phone_number::Reader<'a>>) {
                                                                                               ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:153:65: 153:113 error: use of undeclared type name `person_capnp::person::phone_number::Reader`
src/schema/person_capnp.rs:153     pub fn set_phones(&mut self, value : struct_list::Reader<'a,::person_capnp::person::phone_number::Reader<'a>>) {
                                                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:157:69: 157:81 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:157     pub fn init_phones(self, size : u32) -> struct_list::Builder<'a,::person_capnp::person::phone_number::Builder<'a>> {
                                                                                                   ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:157:69: 157:118 error: use of undeclared type name `person_capnp::person::phone_number::Builder`
src/schema/person_capnp.rs:157     pub fn init_phones(self, size : u32) -> struct_list::Builder<'a,::person_capnp::person::phone_number::Builder<'a>> {
                                                                                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:164:35: 164:47 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:164     pub fn get_birthdate(self) -> ::person_capnp::date::Builder<'a> {
                                                                 ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:164:35: 164:68 error: use of undeclared type name `person_capnp::date::Builder`
src/schema/person_capnp.rs:164     pub fn get_birthdate(self) -> ::person_capnp::date::Builder<'a> {
                                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:168:45: 168:57 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:168     pub fn set_birthdate(&mut self, value : ::person_capnp::date::Reader) {
                                                                           ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:168:45: 168:73 error: use of undeclared type name `person_capnp::date::Reader`
src/schema/person_capnp.rs:168     pub fn set_birthdate(&mut self, value : ::person_capnp::date::Reader) {
                                                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:172:38: 172:50 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:172     pub fn init_birthdate(self, ) -> ::person_capnp::date::Builder<'a> {
                                                                    ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:172:38: 172:71 error: use of undeclared type name `person_capnp::date::Builder`
src/schema/person_capnp.rs:172     pub fn init_birthdate(self, ) -> ::person_capnp::date::Builder<'a> {
                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:187:36: 187:48 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:187     pub fn get_birthdate(&self) -> ::person_capnp::date::Pipeline {
                                                                  ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:187:36: 187:66 error: use of undeclared type name `person_capnp::date::Pipeline`
src/schema/person_capnp.rs:187     pub fn get_birthdate(&self) -> ::person_capnp::date::Pipeline {
                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:244:39: 244:51 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:244       pub fn get_type(self) -> Option<::person_capnp::person::phone_number::Type> {
                                                                     ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:244:39: 244:81 error: use of undeclared type name `person_capnp::person::phone_number::Type`
src/schema/person_capnp.rs:244       pub fn get_type(self) -> Option<::person_capnp::person::phone_number::Type> {
                                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:308:39: 308:51 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:308       pub fn get_type(self) -> Option<::person_capnp::person::phone_number::Type> {
                                                                     ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:308:39: 308:81 error: use of undeclared type name `person_capnp::person::phone_number::Type`
src/schema/person_capnp.rs:308       pub fn get_type(self) -> Option<::person_capnp::person::phone_number::Type> {
                                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:312:42: 312:54 error: failed to resolve. Maybe a missing `extern crate person_capnp`?
src/schema/person_capnp.rs:312       pub fn set_type(&mut self, value : ::person_capnp::person::phone_number::Type) {
                                                                        ^~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
src/schema/person_capnp.rs:312:42: 312:84 error: use of undeclared type name `person_capnp::person::phone_number::Type`
src/schema/person_capnp.rs:312       pub fn set_type(&mut self, value : ::person_capnp::person::phone_number::Type) {
                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of include!
src/schema/mod.rs:2:5: 2:35 note: expansion site
error: aborting due to 24 previous errors
Could not compile `capntest`.

Fixing

Removing schema/mod.rs and making main.rs:

#![feature(path)]

extern crate capnp;
extern crate capnpc;

mod person_capnp {
    include!("./schema/person_capnp.rs");
}

use person_capnp::person;

fn main() {

}

Seems to resolve the issue.

This seems to be related to https://github.com/dwrensha/capnproto-rust/issues/16

dwrensha commented 9 years ago

Yeah, this is the same problem as https://github.com/dwrensha/capnproto-rust/issues/16. I'm closing that issue in favor of this one.

novacrazy commented 7 years ago

My hacky solution to this was to tweak the root_name and root_mod variables in codegen.rs like so:

capnpc root

The {0} in the format string was just because I was experimenting with it and never changed it back to normal.

Then my crate could be organized like:

pub mod my_protocol {
    pub mod protocol {
        include!(concat!(env!("OUT_DIR"), "/protocols/my_protocol_capnp.rs"));
    }
}

...including having them in different files, of course.

Anyway, would it be preferable to simply pass some prefix and postfix strings to the codegen to get the desired module structure, instead of just placing everything in the crate root? If it's done in the build script, we have the full filepath anyway so some more complex things could be done on a per-crate basis.

Or since it's done in the build stage and formatting performance doesn't matter too much for codegen, having a dynamic format string using Handlebars or something would be nifty.

dwrensha commented 7 years ago

I think the right way to do this would be to define some annotations, as I've suggested here, and read them during codegen.

novacrazy commented 7 years ago

Huh. That would be pretty nifty. Although having higher level options for use in the build script would also be nice if all the capnp generated modules would have similar paths like with what I did.

tynril commented 7 years ago

I've encountered this issue when trying to avoid using any include!, as it doesn't play well with RLS/Racer (see this issue, which conveniently references Cap'n'proto as the use case: https://github.com/racer-rust/racer/issues/191).

While it would be possible to get working completion by fixing this issue in Racer and RLS, the use of include! is explicitly discouraged in its documentation, so I think it would be better to change that behavior here rather than there.

eberkund commented 6 years ago

It seems to work in a submodule as long as you still have extern crate capnp; in your main.rs.

dwrensha commented 6 years ago

@eberkund Does your example have any fields that reference structs in the same schema. E.g.


struct Foo {}

struct Bar {
  foo @0 : Foo;
}

I would expect this to fail if included in a submodule, because the generated references to Foo will be absolute paths like ::example_capnp::foo::Reader.

eberkund commented 6 years ago

@dwrensha Oh yea, you are correct. It is a very simple schema without any types depending on one another like you described.

dwrensha commented 6 years ago

Closing again in favor of https://github.com/capnproto/capnproto-rust/issues/16, as capnpc-rust has been moved back to that repo.