[solved] Trait error E0277 in a basic serde_json program


#1

Not sure if this is the right place to post this. Feel free to re-direct if this is too specific to serde_json.

I copied and pasted this three-line code snippet from the serde_json examples. I’m sure I’m missing something basic, but this error is too dense for me.

Here’s the code:

extern crate serde_json;

use serde_json::Value;

fn main() {
    let data = r#" { "name": "John Doe", "age": 43, "phones": ["1234"] } "#;
    let v: Value = serde_json::from_str(data)?;
    println!("Please call {} at the number {}", v["name"], v["phones"][0]);
}

And build output:

$ rustc --version
rustc 1.15.1 (021bd294c 2017-02-08)
$ tail -n2 Cargo.toml
[dependencies]
serde_json = "0.9"
$ cargo run
   Compiling test_json v0.1.0 (file:///Users/elliott/Programming/Rust/test_json)
error[E0277]: the trait bound `(): std::ops::Carrier` is not satisfied
 --> src/main.rs:7:20
  |
7 |     let v: Value = serde_json::from_str(data)?;
  |                    ---------------------------
  |                    |
  |                    the trait `std::ops::Carrier` is not implemented for `()`
  |                    in this macro invocation
  |
  = note: required by `std::ops::Carrier::from_error`

I’m a little weirded out because the docs for Carrier seem to show it’s unstable. But I’m pretty sure I’m on the stable channel (see rustc --version above). I believe recent versions of serde/serde_json should work on stable, but if that’s not the case then obviously that would be an issue.

Barring that, I really don’t see what the issue is. from_str returns Result, the ? operator should return Value, so… where is () coming from?

Is the problem that main returns () and therefore ? doesn’t have anywhere to propagate the error to? If so how do I just get it to panic when I’m unwrapping an error value?

This is the sort of thing where better error messages would be really helpful.

Thanks.


#2

You guessed it - the problem is that main returns () and therefore ? cannot early-return a Result. You can get it to panic on error by using serde_json::from_str(data).unwrap() instead.

extern crate serde_json;

use serde_json::Value;

fn main() {
    let data = r#" { "name": "John Doe", "age": 43, "phones": ["1234"] } "#;
    let v: Value = serde_json::from_str(data).unwrap();
    println!("Please call {} at the number {}", v["name"], v["phones"][0]);
}

#3

Thanks, that makes sense.

Next question: Is this the sort of thing where a customized error message would be justified? If so where do I go to report this?


#4

The general issue of ? in main is being discussed in this thread. A customized error message would be nice until they settle on a real solution.



#5

I was getting started with Hyper. https://hyper.rs/guides/client/basic/. But on building, I get this error


error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
  --> src/main.rs:11:20
   |
11 |     let mut core = Core::new()?;
   |                    ------------
   |                    |
   |                    the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
   |                    in this macro invocation
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
  --> src/main.rs:14:15
   |
14 |     let uri = "http://httpbin.org/ip".parse()?;
   |               --------------------------------
   |               |
   |               the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
   |               in this macro invocation
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
  --> src/main.rs:25:5
   |
25 |     core.run(work)?;
   |     ---------------
   |     |
   |     the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
   |     in this macro invocation
   |
   = help: the trait `std::ops::Try` is not implemented for `()`
   = note: required by `std::ops::Try::from_error`

error: aborting due to 3 previous errors

I wanted to know how i can get around this?
please bear with me, I’m new to Rust


#6

That guide seems to be incomplete. @seanmonstar, perhaps it could be tweaked such that a reader can copy/paste and be reasonably sure it’ll work? :slight_smile:

Here’s something that should work (provided futures, hyper, and tokio-core are added to cargo’s Cargo.toml):

extern crate futures;
extern crate hyper;
extern crate tokio_core;

use std::io::{self, Write};
use futures::{Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;
use std::error::Error;

fn main() {
    do_it().unwrap();
}

fn do_it() -> Result<(), Box<Error>> {
    let mut core = Core::new()?;
    let client = Client::new(&core.handle());

    let uri = "http://httpbin.org/ip".parse()?;
    let work = client.get(uri).and_then(|res| {
        println!("Response: {}", res.status());

        res.body().for_each(|chunk| {
            io::stdout()
                .write_all(&chunk)
                .map_err(From::from)
        })
    });
    Ok(core.run(work)?)
}

@faraazahmad, the ? operator can only be used (currently) in functions that return a Result, pretty much as the error message states. Given main doesn’t return anything (or to be precise, it returns ()), you just need to move that code to a helper function, as the example above.


#7

Thanks I’ll give it a shot :+1: