Method not in scope. How is this possible?


#1

edit:
I complained about this to a friend and he suggested deleting Cargo.lock and letting it regen, and sure enough, it builds just fine now. So I guess that solves that, and now I feel silly for not having thought to try this first.

I’m attempting to use serde_json to, well, deserialize some JSON data and use it to show some information to the user. What’s strange is that the compiler is telling me that serde_json::Value doesn’t have the method get in this scope:

error: no method named `get` found for type `serde_json::Value` in the current scope
  --> src/jisho.rs:34:24
   |
34 | 	let data = jisho_json.get("data").unwrap();
   | 	                      ^^^

That doesn’t make sense to me, it’s right there in the docs. A similar thing happens when trying to index a Value:

error: cannot index a value of type `serde_json::Value`
  --> src/jisho.rs:34:13
   |
34 | 	let data = jisho_json["data"];
   | 	

Here’s the code that doesn’t work:

let mut resp = match client.get(url.as_str()).send() {
	//...
};
let mut resp_string = String::new();
let _ = resp.read_to_string(&mut resp_string).unwrap();
let jisho_json: Value = serde_json::from_str(resp_string.as_str()).unwrap();
let data = jisho_json["data"];

What makes this even more mysterious to me is that I have a different project where I do exactly this, and it builds and runs just fine. Could I possibly have done something to break my cargo project?


#2

Which version of serde_json are you using?


#3

I’m using the latest at the time of writing this (0.9.10). However, I edited my post above explaining that deleting Cargo.lock and letting it regenerate fixed the issue, for some reason.


#4

This is problem is usually caused by a version mismatch.

Say that your project C uses 2 libraries A and B, where B also depends on A.

C -+--> B --> A (v X)
   |
   +--------> A (v Y)

The problem arises if they don’t depend on the same version of A. In that case, A (v X) and A (v Y) are considered different libraries.
Usually, you don’t even notice that, except when library B exports functionality from A, e.g. a type that is de/serializable with serde. Now if you try to call a serde-method on that exported type, you are using serde (v Y) while the type only implements serde (v X).

Deleting Cargo.lock usually helps, because it stores the exact versions of the dependencies. A cargo update call would probably have the same effect.