Skip to content
This repository was archived by the owner on Dec 1, 2023. It is now read-only.

Derive RustcDecodable not working when rustc-serialize crate is imported inside a module #61

Closed
mhristache opened this issue Feb 17, 2015 · 6 comments

Comments

@mhristache
Copy link

When importing rustc-serialize inside a module, [derive(RustcDecodable, RustcEncodable)] fails.

The code inside the module file:

extern crate "rustc-serialize" as rustc_serialize;
use self::rustc_serialize::json::{self, ToJson, Json, DecoderError};

#[derive(RustcDecodable, RustcEncodable)]
struct Test {
    test: String
    }

fn test(s: String) -> Test {
    Test {test: s}
    }

When compiling I get the following errors:

$ cargo build
   Compiling serialize_issue v0.0.1 (file://rust-playground/serialize_issue)
src/mod1/mod.rs:4:26: 4:41 error: failed to resolve. Did you mean     `self::rustc_serialize`?
src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                                           ^~~~~~~~~~~~~~~
note: in expansion of #[derive]
src/mod1/mod.rs:4:1: 4:42 note: expansion site
src/mod1/mod.rs:4:26: 4:40 error: attempt to implement a nonexistent trait    `rustc_serialize::Encodable`
src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                                           ^~~~~~~~~~~~~~
 note: in expansion of #[derive]
 src/mod1/mod.rs:4:1: 4:42 note: expansion site
 src/mod1/mod.rs:4:26: 4:41 error: failed to resolve. Did you mean     `self::rustc_serialize`?
 src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                                           ^~~~~~~~~~~~~~~
 note: in expansion of #[derive]
 src/mod1/mod.rs:4:1: 4:42 note: expansion site
 src/mod1/mod.rs:4:26: 4:40 error: attempt to bound type parameter with a nonexistent    trait `rustc_serialize::Encoder`
 src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                                           ^~~~~~~~~~~~~~
 note: in expansion of #[derive]
 src/mod1/mod.rs:4:1: 4:42 note: expansion site
 src/mod1/mod.rs:4:10: 4:25 error: failed to resolve. Did you mean     `self::rustc_serialize`?
 src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                           ^~~~~~~~~~~~~~~
 note: in expansion of #[derive]
 src/mod1/mod.rs:4:1: 4:42 note: expansion site
 src/mod1/mod.rs:4:10: 4:24 error: attempt to implement a nonexistent trait    `rustc_serialize::Decodable`
src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                           ^~~~~~~~~~~~~~
note: in expansion of #[derive]
src/mod1/mod.rs:4:1: 4:42 note: expansion site
src/mod1/mod.rs:4:10: 4:25 error: failed to resolve. Did you mean     `self::rustc_serialize`?
src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                           ^~~~~~~~~~~~~~~
note: in expansion of #[derive]
src/mod1/mod.rs:4:1: 4:42 note: expansion site
src/mod1/mod.rs:4:10: 4:24 error: attempt to bound type parameter with a nonexistent    trait `rustc_serialize::Decoder`
 src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                           ^~~~~~~~~~~~~~
 note: in expansion of #[derive]
 src/mod1/mod.rs:4:1: 4:42 note: expansion site
 src/mod1/mod.rs:4:10: 4:25 error: failed to resolve. Did you mean     `self::rustc_serialize::Decodable`?
 src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                           ^~~~~~~~~~~~~~~
 note: in expansion of #[derive]
 src/mod1/mod.rs:4:1: 4:42 note: expansion site
 src/mod1/mod.rs:4:10: 4:24 error: unresolved name `rustc_serialize::Decodable::decode`
 src/mod1/mod.rs:4 #[derive(RustcDecodable, RustcEncodable)]
                           ^~~~~~~~~~~~~~
 note: in expansion of #[derive]
 src/mod1/mod.rs:4:1: 4:42 note: expansion site
 error: aborting due to 10 previous errors
 Could not compile `serialize_issue`. 

The issue can be workaround by moving the imports to the lib.rs file.

$ cat src/mod1/mod.rs 
use super::rustc_serialize::json::{self, ToJson, Json, DecoderError};

#[derive(RustcDecodable, RustcEncodable)]
struct Test {
    test: String
    }

fn test(s: String) -> Test {
    Test {test: s}
    }

$ cat src/lib.rs 
extern crate "rustc-serialize" as rustc_serialize;
mod mod1;
@gbersac
Copy link

gbersac commented Apr 25, 2015

I think it is best practice to move all the extern crate statement in the lib.rs/main.rs file. That's what I always do.

@rking788
Copy link

rking788 commented May 9, 2015

I should have checked the github issues first. Thanks for the feedback @gbersac.

@darxriggs
Copy link

I am new to Rust and this issue bit me within minutes and I took me some time to find it here.

So the question is, can this be fixed in the crate itself or is this a fundamental issue?

The current usage statement didn't click for me:

Add this to your crate root: extern crate rustc_serialize;

So in the meantime it would be a good idea to update the usage section in README.md to mention main.rs and lib.rs explicitly. And to state if used anywhere else this issue applies.

@moll
Copy link

moll commented Apr 28, 2016

Is the crate root requirement a limitation of derive and worked on somewhere? I don't particularly think coupling submodules with the crate root this way is a good practice.

@dtolnay
Copy link
Contributor

dtolnay commented Feb 2, 2017

This is not a limitation of derive. In particular, Serde does not have this problem.

The code generated by RustcEncodable and RustcDecodable looks like this:

impl ::rustc_serialize::Encodable for Test { /* ... */ }
impl ::rustc_serialize::Decodable for Test { /* ... */ }

which requires rustc_serialize to be in the crate root.

In Serde we avoid this problem by generating the following code instead:

const IMPL_SERIALIZE_FOR_Test: () = {
    extern crate serde as _serde;
    impl _serde::Serialize for Test { /* ... */ }
};
const IMPL_DESERIALIZE_FOR_Test: () = {
    extern crate serde as _serde;
    impl _serde::Deserialize for Test { /* ... */ }
};

This works whether or not serde is in the crate root, in fact whether or not you even import serde anywhere yourself.

@alexcrichton
Copy link
Contributor

I'm going to close this now that this crate is deprecated in favor of serde. We're discontinuing feature development in rustc-serialize but will still continue to merge bug fixes if they arise.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants