I am implementing a proc macro, and testing in another crate. When I compile the client crate, there is an error thrown from the invocation site of the proc macro:
error: proc macro panicked
--> foo/src/main.rs:17:1
The error is occurring within the proc macro implementation.
This error is not very helpful, because it doesn't point me to where specifically is failing. It's possible to figure it out using unique error messages, but it would be much simpler to have an exact file and line number where the error originates in the proc macro implementation as part of the trace.
Is there any way to achieve this?
There's a nightly rustc flag, -Zproc-macro-backtrace, that prints a backtrace when a proc macro panics.
Note this is a rustc flag, not a Cargo flag, and so you need to invoke it like so:
cargo +nightly rustc -- -Zproc-macro-backtrace
You can also use RUSTFLAGS:
RUSTFLAGS="-Zproc-macro-backtrace" cargo check
Related
quick introduction, I came from python I have studied it by myself, and now I'm trying to learn Rust. I find it a bit confusing.
I have a main.rs file and other .rs files in the src directory just to have cleaner and organized code, as each of these other files do specific tasks and the main.rs just put all together with a simple CLI.
I just wanna test a single of these .rs file, or even a single fn inside to check if the result is what I am expecting.
How can I do that? It's simple, it's stupid, but I have read around and found nothing that could help me in the end.
I read this, where it talks about making a tests folder and then using cargo test, I've done it, but it still runs the src/main.rs instead of what I have put in tests. BTW I'm using CLion with the Rust plugin.
Sorry if this is somewhat a duplicate, I looked around but I didn't found an answer.
This funcitonality is not really part of Rust itself, but there are some crates that do it. The one I'm most familiar with is rust-script. It works with a hashbang like #!/usr/bin/env rust-script at the top of your script, then run it with ./script.rs. You can even specify dependencies in the script which get parsed out of some special comments.
Edit: Sorry yes - it looks like you're trying to write/run tests. The page you linked in the book should cover what you're trying to do. I'm not sure what you mean by "it still runs the src/main.rs instead of what I have put in tests". Do you have mod tests in main.rs as well?
you can compile any .rs file using rustc your_file.rs command as long as the file contains main() function. rustc will fail if there isn't main function:
error[E0601]: `main` function not found in crate `abc`
--> abc.rs:5:2
|
5 | }
| ^ consider adding a `main` function to `abc.rs`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0601`.
but you can skip this by marking the file as library crate instead of bin:
rustc you_file.rs --crate-type=lib
Due to how the LGPL works, compiling Rust code to an object file without linking would be useful to be able to do. However, I cannot find any documentation on how to do this. I checked rustc's help section and searched, but couldn't find anything, which brings me to my question: How do I tell rustc to not link and produce object files that later can be linked?
Use the compiler flag --emit=obj.
cargo rustc -- --emit=obj
The compiled object files will be sitting in target/debug/deps.
See also:
How to pass rustc flags to cargo?
I'm writing a program in Rust and I have some tests for it. I wrote a helper function for these tests, but whenever I build using cargo build it warns me that the function is never used:
warning: function is never used: ... #[warn(dead_code)] on by default
How I can mark this function as used so as not to get the warnings?
Specific question
How I can mark this function as used so as not to get the warnings?
The Rust compiler runs many lints to warn you about possible issues in your code and the dead_code lint is one of them. It can be very useful in pointing out mistakes when code is complete, but may also be a nuisance at earlier stages. Often, this can be solved by either deleting unused code, or by marking a public method. However, all lints can be turned off by allowing them, and your error message (#[warn(dead_code)] on by default) contains the name of the lint you could disable.
#[allow(dead_code)]
fn my_unused_function() {}
Alternative for testing
I wrote a helper function for these tests, but whenever I build using cargo build it warns me that the function is never used.
This happens to be a special case, which is that code that is only used for testing isn't needed in the real executable and should probably not be included.
In order to optionally disable compilation of test code, you can mark it accordingly using the cfg attribute with the test profile.
#[cfg(test)]
fn my_test_specific_function() {}
When marked in this way, the compiler knows to ignore the method during compilation. This is similar to commonly used ifdef usage in other languages like C or C++, where you are telling a preprocessor to ignore the enclosed code unless TESTING is defined.
#ifdef TESTING
...
#endif
For people getting this warning while making a rust library, you may get this if you don't have your modules set to pub in your lib.rs.
pub mod foo;
If something is only used in tests, it should be omitted altogether. This can be done with the #[cfg(test)] attribute.
dead_code is a lint, which means you can allow it on the thing that's causing it to trigger.
#[allow(dead_code)]
fn dummy() {}
fn main() {}
There is another situation where this can occur. If you have several helper functions in a module, e.g. in tests/utils/mod.rs and then several integration tests (tests/a.rs, tests/b.rs) each of which does
mod utils;
use utils::...;
then you will get dead code warnings if you do not use all of the code from all of the tests. For example if test a.rs only uses utils::foo and b.rs only uses utils::bar then you will get dead code warnings for both.
That is because each test is compiled as an independent crate. Here is the bug report for it. It looks difficult to solve so I wouldn't hold my breath.
You can disable specific lints for a whole project in Rust by going into your main.rs file and adding the following at the very top of the file:
#![allow(
dead_code,
unused_imports
)]
You max prefix the unused function name with an underscore:
fn _dummy() {}
fn main() {}
See: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dead-code
For some reason I found that setting the main function to public:
pub fn main()
and then copying my main.rs file to lib.rs
cp src/main.rs src/lib.rs
then recompiling fixed this.
No need to use a macro for it, although the macro should work for non main functions.
I'm trying to pass my whole crate to a procedural macro.
I've tried putting this code on top of my lib.rs:
#![my_macro]
#![feature(proc_macro)]
extern crate my_macro;
use my_macro::{my_macro};
and failed: error: cannot find attribute macro 'my_macro' in this scope
I've tried also putting the macro invocation below the use clause:
#![feature(proc_macro)]
extern crate my_macro;
use mock_macro::{my_macro};
#![my_macro]
but failed as well: error: an inner attribute is not permitted in this context
Is it possible to do it? (I know syn has a function for parsing a whole crate)
This is possible as of Rust 1.25.0-nightly as long as you enable feature(extern_absolute_paths) and use an absolute path for your attribute macro.
#![::my_crate::my_macro]
#![feature(extern_absolute_paths, proc_macro)]
The issue of attribute macros invoked at the crate root is being tracked in rust-lang/rust#41430. We expect to remove the limitation that the attribute must be specified with an absolute path as the implementation of RFC 2126 proceeds further. You may run into other limitations too, in particular attempting to inject functions into the crate from a crate-level procedural macro currently crashes the compiler.
Several documents for Rust mention the fail! function as a way to abort execution with an error.
For example, chapter 27 of Rust By Example (accessed November 16, 2014) states:
The fail! macro can be used to generate a task failure and start unwinding its stack. While unwinding, the runtime will take care of freeing all the resources owned by the task by calling the destructor of all its objects.
However when I try to use this in my own code I get the following error:
error: macro undefined: 'fail!'
You can click "Run" on the example on the "Rust By Example" page to reproduce for yourself.
What took the place of fail in the Rust standard library?
It has been renamed to panic!, see Issue 17489 and the nightly doc