Unresolved import when calling a macro defined in an external crate - rust

I am trying to implement a custom HTTP header using impl_header macro from hyper crate but it seems it cannot resolve the hyper::header module.
Here is my code:
#[macro_use] extern crate hyper;
use hyper::header;
struct CustomHeader;
impl_header!(CustomHeader, "value", String);
And here is the compiler error:
<hyper macros>:11:14: 11:20 error: unresolved import `header::HeaderFormat`. Maybe a missing `extern crate header`?
<hyper macros>:11 Result { use header:: HeaderFormat ; self . fmt_header ( f ) } } }
^~~~~~
<hyper macros>:1:1: 11:67 note: in expansion of impl_header!
lib.rs:4:1: 4:45 note: expansion site
error: aborting due to previous error
Could not compile `macro_issue`.
Any clue why this happens and how can I fix it?
Thank you

I agree with Renato that this is an issue with hyper, and you should file a bug (or even better a pull request!). If you'd like to work around it for now though, you can re-export header as your own:
#[macro_use]
extern crate hyper;
pub use hyper::header as header;
struct CustomHeader;
impl_header!(CustomHeader, "value", String);
fn main() {}
Unfortunately, this simply unlocks a whole new wave of errors that I'll let you figure out!

Related

An opened image as a global variable?

I'd like to write a server that resizes a huge image. Since loading it on every request would take a lot of time, I decided to pre-load it. Unfortunately I got the following error:
Compiling hello_world v0.0.0 (/tmp/Rocket/examples/hello_world)
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
--> examples/hello_world/src/main.rs:9:35
|
9 | static img: image::DynamicImage = image::open("/home/d33tah/tmp/combined.png").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
--> examples/hello_world/src/main.rs:9:35
|
9 | static img: image::DynamicImage = image::open("/home/d33tah/tmp/combined.png").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0015`.
error: Could not compile `hello_world`.
To learn more, run the command again with --verbose.
Here's the code:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[cfg(test)] mod tests;
extern crate image;
static img: image::DynamicImage = image::open("/home/d33tah/tmp/combined.png").unwrap();
#[get("/")]
fn hello() -> Vec<u8> {
"".into()
}
fn main() {
rocket::ignite().mount("/", routes![hello]).launch();
}
To compile it, you'll need rocket installed based on its latest Github checkout (currently: 831d8dfbe30dd69f0367a75361e027127b2100e1) and image crate.
Is it possible to create such a global variable? If not, do I have any other options?
EDIT: this was flagged as a duplicate of this question, but as Boiethios showed, this specific case is better solved by Rocket's API.
If you want to share something in Rocket, you will have to use a managed state:
Say to Rocket you want to manage the resource:
let image = image::open("/home/d33tah/tmp/combined.png").unwrap();
rocket::ignite().manage(image);
Retrieve it in the routes where you need it:
#[get("/foo")]
fn foo(image: State<DynamicImage>) {
// Can use `image`.
}

Missing `start` lang_item when using Real-Time For the Masses

I'm trying to write a multi-threaded bare-metal application for the STM32F4Discovery using the Real-Time For the Masses (RTFM) crate. I've frankensteined together a minimal application from an example for the STM32F3Discovery board and this example:
#![no_std]
extern crate cortex_m;
extern crate cortex_m_rtfm as rtfm;
extern crate cortex_m_semihosting;
extern crate panic_semihosting;
extern crate stm32f4;
use stm32f4::stm32f407;
use rtfm::app;
app! {
device: stm32f407,
}
fn init(_p: init::Peripherals) {
}
fn idle() -> ! {
loop {
rtfm::wfi();
}
}
Compilation fails with
error: requires `start` lang_item
I'm new to Rust (in fact I was hoping to learn the language with this project) and have no idea where the error might be located. Is it just that the app! macro is broken or am I missing something?
I've found a workaround in RTFM's issues on GitHub that allows to compile the code above:
import cortex-m-rt and its entry macro
#[macro_use(entry)]
extern crate cortex_m_rt as rt;
add #![no_main] to the head of the source
wrap the main function using the entry macro:
#[entry]
fn entry_wrap() -> ! {
main();
loop {}
}
I haven't tested this yet but it compiles without problems.

Is there a way to import macros from an external crate during tests only, without any warnings?

I have something like:
#[macro_use] extern crate log;
pub fn do_nothing() { let _ = log::Level::Info; }
#[cfg(test)]
mod tests {
#[test]
fn test_a() { debug!("Message."); }
}
this compiles with a warning:
warning: unused `#[macro_use]` import
If I remove the macro import, and change the 1st line to:
extern crate log;
then I get the following error at compile time:
error: cannot find macro `debug!` in this scope
If I then try and import the macros only for the tests module, i.e.:
extern crate log;
pub fn do_nothing() { let _ = log::Level::Info; }
#[cfg(test)]
mod tests {
#[macro_use] extern crate log;
#[test]
fn test_a() { debug!("Message."); }
}
then I get the compiler error:
error[E0468]: an `extern crate` loading macros must be at the crate root
Is there a solution which avoids all warnings without just suppressing them?
You can use cfg_attr:
#[cfg_attr(test, macro_use)]
extern crate log;
See also:
Is it possible to conditionally derive with features?
Can I conditionally compile my Rust program for a Windows subsystem?
Run additional tests by using a feature flag to "cargo test"

Importing a crate into a const block

I'm trying to write a procedural macro that implements a #[derive()] trait for a struct. In the generated implementation code I need to use AnyMap.
To avoid multi crate imports, and based on what I read in some other crate's code (namely Serde) I put my generated code into a const _IMPL_xxx_FOR_xxx : () = { /* generated code */ }; block but it fails to compile.
I was able to replicate my issue with the following code
const BLOCK_1: () = {
extern crate anymap;
use anymap::AnyMap;
};
const BLOCK_2: () = {
extern crate anymap;
use anymap::AnyMap;
};
fn main() {
println!("foo");
}
The compile error I'm getting is the following:
error[E0432]: unresolved import `anymap::AnyMap`
--> src/main.rs:3:9
|
3 | use anymap::AnyMap;
| ^^^^^^^^^^^^^^ Maybe a missing `extern crate anymap;`?
error[E0432]: unresolved import `anymap::AnyMap`
--> src/main.rs:9:9
|
9 | use anymap::AnyMap;
| ^^^^^^^^^^^^^^ Maybe a missing `extern crate anymap;`?
Is it an issue specific to AnyMap? Would you know of any way to fix this (including maybe a different approach to generating procedural macro code if the pattern I'm using is not recommended?
I can replicate this on the playground using simply
const A: () = {
extern crate core;
use core::option::Option;
};
fn main() {}
However, it appears only the use statement is broken, and I can still use items from core, but I have to name them explicitly each time:
const A: () = {
extern crate core;
do_stuff!(core::option::Option)
};
The reason is that use statements typically assume a path relative to the root, and there is no way to explicitly name the block you are in (self refers to the current module unfortunately).
Here's a better workaround - as I said before, Rust uses self to refer to the current module, so you can just put a module in your code block and then have the use statements reference self.
In your case it would be:
const BLOCK_1: () = {
mod inner {
extern crate anymap;
use self::anymap::AnyMap;
}
};
On the specific issue of making this work for procedural macro, a suggested solution was to reexport the needed crate as part of the crate containing the derive macro (or the one containing the class I'm trying to export) using something like pub extern crate anymap and then use <my_crate>::anymap::AnyMap;

How do I use a macro defined in another crate?

I've seen a couple tutorials to create a Python module using the cpython crate but still have errors when building:
extern crate cpython;
use cpython::{PyObject, PyResult, Python, PyTuple, PyDict, ToPyObject, PythonObject};
fn add_two(py: Python, args: &PyTuple, _: Option<&PyDict>) -> PyResult<PyObject> {
match args.as_slice() {
[ref a_obj, ref b_obj] => {
let a = a_obj.extract::<i32>(py).unwrap();
let b = b_obj.extract::<i32>(py).unwrap();
let mut acc:i32 = 0;
for _ in 0..1000 {
acc += a + b;
}
Ok(acc.to_py_object(py).into_object())
},
_ => Ok(py.None())
}
}
py_module_initializer!(example, |py, module| {
try!(module.add(py, "add_two", py_fn!(add_two)));
Ok(())
});
I get:
error: macro undefined: 'py_module_initializer!'
Where do I get it? I am using Rust 1.12.
UPD
Need to add #[macro_use] (as in answers)
For other errors - see examples here
You probably need to declare cpython as follows:
#[macro_use] extern crate cpython;
To be able to use cpython's macros. You can consult the example in its docs.
You must add the #[macro_use] attribute on the extern crate declaration to ask the compiler to bring the macros exported by the crate into your crate's namespace.
#[macro_use]
extern crate cpython;

Resources