carllerche / tower-web

A fast, boilerplate free, web framework for Rust
MIT License
980 stars 51 forks source link

Can't create a generic service with impl_web? #141

Closed pwoolcoc closed 5 years ago

pwoolcoc commented 5 years ago

Hello, I'm trying to create a service that has a generic parameter and I'm getting an error. Here is some example code:

#[macro_use] extern crate tower_web;
use std::error::Error;
use std::fmt::Display;

struct HelloWorld<S>(pub S);

impl_web! {
    impl<S: Display> HelloWorld<S> {
        #[get("/")]
        fn hello(&self) -> Result<String, Box<Error>> {
            let r = self.0.to_string();
            Ok(r)
        }
    }
}

fn main() {
    println!("Hello, world!");
}

and here is the error when I go to compile it:

~/c/test-tower-project> cargo check
    Checking test-tower-project v0.1.0 (/home/paul/code/test-tower-project)                                                                                                                   
error[E0412]: cannot find type `S` in this scope                                                                                                                                              
  --> src/main.rs:7:1                                                                                                                                                                         
   |                                                                                                                                                                                          
7  | / impl_web! {                                                                                                                                                                            
8  | |     impl<S: Display> HelloWorld<S> {                                                                                                                                                   
9  | |         #[get("/")]                                                                                                                                                                    
10 | |         fn hello(&self) -> Result<String, Box<Error>> {                                                                                                                                
...  |                                                                                                                                                                                        
14 | |     }                                                                                                                                                                                  
15 | | }                                                                                                                                                                                      
   | |_^ did you mean `U`?                                                                                                                                                                    
   |                                                                                                                                                                                          
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)                                              

error[E0599]: no method named `hello` found for type `HelloWorld<S>` in the current scope                                                                                                     
  --> src/main.rs:7:1                                                                                                                                                                         
   |                                                                                                                                                                                          
5  |   struct HelloWorld<S>(pub S);                                                                                                                                                           
   |   ---------------------------- method `hello` not found for this                                                                                                                         
6  |                                                                                                                                                                                          
7  | / impl_web! {                                                                                                                                                                            
8  | |     impl<S: Display> HelloWorld<S> {                                                                                                                                                   
9  | |         #[get("/")]                                                                                                                                                                    
10 | |         fn hello(&self) -> Result<String, Box<Error>> {                                                                                                                                
...  |                                                                                                                                                                                        
14 | |     }                                                                                                                                                                                  
15 | | }                                                                                                                                                                                      
   | |_^                                                                                                                                                                                      
   |                                                                                                                                                                                          
   = note: the method `hello` exists but the following trait bounds were not satisfied:                                                                                                       
           `S : std::fmt::Display`                                                                                                                                                            
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)                                              

error: aborting due to 2 previous errors                                                                                                                                                      

Some errors occurred: E0412, E0599.                                                                                                                                                           
For more information about an error, try `rustc --explain E0412`.                                                                                                                             
error: Could not compile `test-tower-project`.                                                                                                                                                

To learn more, run the command again with --verbose.

Is there a way around this? I assume it's a problem with the proc-macro but I'm really not sure what to do about it, other than to have my service use boxed trait objects instead of monomorphization.

carllerche commented 5 years ago

It's a bug. I will try to fix.

pwoolcoc commented 5 years ago

thanks!

carllerche commented 5 years ago

143 includes a fix. Would you be able to check if it fixes your particular case?

I pulled in your repro to the tests, so unless you have something more complicated that isn't supported yet, it should work.

pwoolcoc commented 5 years ago

@carllerche LGTM, thanks!