Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc can no longer resolve my imports inside quote!{}. #303

Closed
seunlanlege opened this issue Jan 8, 2018 · 2 comments
Closed

rustc can no longer resolve my imports inside quote!{}. #303

seunlanlege opened this issue Jan 8, 2018 · 2 comments

Comments

@seunlanlege
Copy link

seunlanlege commented Jan 8, 2018

I'm currently writing a library arc-reactor, due to time constraints, i abandoned it for a while. But now i'm trying to pick up where i left off, and there are some errors i don't understand. I use proc-macros in the project for code generation.

cargo.toml

[package]
name = "impl-service"
version = "0.1.0"
authors = ["seunlanlege <[email protected]>"]

[dependencies]
quote = { git = 'https://github.com/dtolnay/quote' }
proc-macro2 = { version = "*", features = ["unstable"] }


[lib]
proc-macro = true

[dependencies.syn]
git = 'https://github.com/dtolnay/syn'
features = ["full", "fold", "parsing", "printing", "extra-traits"]
default-features = false
#[proc_macro_attribute]
pub fn service(_attribute: TokenStream, function: TokenStream) -> TokenStream {
	let item = syn::parse(function)
		.expect("Well, that didn't work. Must be a syntax error.");
	let ItemFn {
		ident,
		block,
		decl,
		..
	} = match item {
		Item::Fn(item) => item,
		_ => panic!("#[service]: Whoops!, try again. This time, with a function."),
	};
	
	let block = block.stmts.iter();
	let inputs = decl.inputs.into_tokens();
	
	let output = quote! {
		struct #ident;
		
		impl ArcService for #ident {
			fn call(&self, #inputs) -> Box<Future<Item = Response, Error = Error>> {
				Box::new(
					async_block!{
						#(
							#block
						)*
					}
				)
			}
		}
	};
       println!("{}", &output)

	output.into()
}

to be used as

#[service]
fn RequestHandler(request: Request, res: Response) {
	let url = request.map.get::<Params>().unwrap();
	let body = format!("Hello {}", url["username"]);
	let res =	res
		.with_status(StatusCode::Ok)
		.with_body(body);

	Ok(res)
}

which should generate

struct RequestHandler; 
impl ArcService for RequestHandler {
  fn call (&self , request: Request , res: Response ) -> Box<Future<Item= Response , Error=Error>> {
    Box :: new (
      async_block ! {
        let url = request.map.get::<Params>().unwra ();
        let body = format!("Hello {}" , url[ "username" ]);
        let res = res.with_status (StatusCode :: Ok)
           .with_body(body);
        Ok(res)
      }
   )
  } 
}

which it actually does, but when i compile it i get, these

~/Projects/async-server on  redesign [!?] 
➜ cargo run                                                                                                                                                                                ⏎ redesign ✱ ◼
   Compiling async-server v0.1.0 (file:///home/seunlanlege/Projects/async-server)
struct RequestHandler ; impl ArcService for RequestHandler {
fn call ( & self , request : Request , res : Response ) -> Box < Future < Item
= Response , Error = Error >> {
Box :: new (
async_block ! {
let url = request . map . get :: < Params > (  ) . unwrap (  ) ; let body =
format ! ( "Hello {}" , url [ "username" ] ) ; let res = res . with_status (
StatusCode :: Ok ) . with_body ( body ) ; Ok ( res ) } ) } }
error: cannot find macro `async_block!` in this scope
  --> src/main.rs:51:1
   |
51 | #[service]
   | ^^^^^^^^^^

error[E0405]: cannot find trait `ArcService` in this scope
  --> src/main.rs:51:1
   |
51 | #[service]
   | ^^^^^^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
   |
24 | use ArcProto::service::ArcService;
   |

error[E0412]: cannot find type `Future` in this scope
  --> src/main.rs:51:1
   |
51 | #[service]
   | ^^^^^^^^^^ not found in this scope
help: possible candidates are found in other modules, you can import them into scope
   |
24 | use futures::Future;
   |
24 | use futures::future::Future;
   |
24 | use futures::prelude::Future;
   |

error[E0412]: cannot find type `Response` in this scope
  --> src/main.rs:51:1
   |
51 | #[service]
   | ^^^^^^^^^^ not found in this scope
help: possible candidates are found in other modules, you can import them into scope
   |
24 | use ArcCore::response::Response;
   |
24 | use hyper::Response;
   |
24 | use hyper::client::Response;
   |
24 | use hyper::server::Response;
   |

error[E0412]: cannot find type `Error` in this scope
  --> src/main.rs:51:1
   |
51 | #[service]
   | ^^^^^^^^^^ not found in this scope
help: possible candidates are found in other modules, you can import them into scope
   |
24 | use hyper::Error;
   |
24 | use hyper::error::Error;
   |
24 | use std::error::Error;
   |
24 | use std::fmt::Error;
   |
and 1 other candidates

error: aborting due to 5 previous errors

error: Could not compile `async-server`.

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

all the missiing deps rustc is complaining about are all imported

#![feature(
proc_macro,
box_syntax,
generators,
)]

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]

extern crate anymap;
extern crate impl_service;
extern crate num_cpus;
extern crate tokio_core;
extern crate route_recognizer as recognizer;
extern crate futures_await as futures;
extern crate hyper;

mod ArcRouting;
mod ArcCore;
#[macro_use]
mod ArcProto;

use recognizer::Params;
use impl_service::{service, middleware};
use hyper::{Error, StatusCode};
use futures::future::Future;
use futures::prelude::{async_block};

I really don't know how to debug this, the code used to work. and now it no longer doesn't.

@seunlanlege seunlanlege changed the title rustc can no longer resolve my imports inside quote. rustc can no longer resolve my imports inside quote!{}. Jan 8, 2018
@seunlanlege
Copy link
Author

@dtolnay @alexcrichton @killercup please help 😢

@dtolnay
Copy link
Owner

dtolnay commented Jan 8, 2018

I believe this has to do with whether certain tokens are resolved at the "call site" or at the "def site". Tokens that resolve at the call site resolve to things that are in scope in the code where the macro is called i.e. the code containing #[service] in your case. This is the default (well, the only possible) behavior for macros 1.1-style string based procedural macros. Tokens that resolve at the def site may only resolve to things brought into scope by the generated code such as by doing extern crate or use. This is the new default behavior for all tokens originating from quote!.

Some useful resources:

@dtolnay dtolnay closed this as completed Jan 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants