rustdoc no_main "crate-level attribute should be in the root module" - rust

When using the no_main outer attribute in Rust, cargo doc complains about unused attribute and that crate-level attribute should be in the root module.
I am using Cargo 1.42.0-nightly.
Relevant code:
// main.rs
#![no_main]
This only happens when invoking cargo doc; cargo build works as expected.
I have seen https://github.com/rust-lang/rust/issues/62184, which however does not contain any answer.
I have also seen https://github.com/rust-lang/rust/issues/43144, from where I followed to https://github.com/rust-lang/rust/pull/64471, but even though that merge request is already merged, the problem remains.
How to solve this warning?

This warning is caused by known bug in cargo/rustdoc which has however not yet been fixed.
As of now, this can be easily worked around by using the cfg_attr attribute in combination with the rustdoc's cfg(doc) in the following way:
// main.rs
#![cfg_attr(not(doc), no_main)]
This code applies the no_main attribute in all cases, except when the documentation is building.

Related

run specific .rs file

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

How to turn off cargo doc test and compile for a specific module in Rust

I have some generated .rs code (from grpc proto files) and they are checked in with my normal Rust code under src but in some sub modules. The issue is that when doing cargo test the doc test will run and some of the generated .rs have comments with indentations (code blocks) and cargo doc test will try to compile them and fail.
For example cargo test will try to compile (and perhaps run these lines) show here.
Is there a way to exclude or ignore those generated .rs for doc test (without manually changing them)?
My solution
I've resolved this by injecting code that separates the offending comment and the structure underneath:
fn main() {
tonic_build::configure()
.type_attribute(
".google.api.HttpRule",
"#[cfg(not(doctest))]\n\
#[allow(dead_code)]\n\
pub struct HttpRuleComment{}\n\
/// HACK: see docs in [`HttpRuleComment`] ignored in doctest pass",
)
.compile(
&["proto/api/google/api/http.proto"],
&["proto/"],
)
.unwrap();
}
Explanation:
tonic_build allows adding attributes to specific protobuf paths, but it does not discern between attributes or any other strings.
#[cfg(not(doctest))] excludes the comment's offending code from doc tests, because it excludes the structure it's added to, this trick is taken from discussion on Rust user forum.
#[allow(dead_code)] silences warnings about injected structure not being used (as it shouldn't be used).
pub struct HttpRuleComment{} creates a public structure that can be referenced in the docstring for the original struct.
/// ...[HttpRuleComment]... is a docstring referencing injected struct, so that the original documentation can still be accessed.
Notes:
I'm not sure if your case is the same, but I found myself on this SO page a lot while searching for an answer and decided to share the results.
In my case, the only offending comment was in HttpRule, you may need to write a macro or do lots of copy-paste if you happen to have multiple offending comments.

What is current documentation tool for Rust? [duplicate]

How can I make cargo to save-analysis? I know that I can do this with rustc by calling
rustc -Zsave-snalysis <files...>
But, I couldn't figure out for cargo. And also I like to know how I can read them back to rls_analysis data structures.
I tried cargo rustc -Zsave-analysis, but it doesn't seem to work.
I also tried export RUSTC_SAVE_ANALYSIS=api, no work too.
What I want to do is getting fully qualified path (e.g. ::foo1::foo2::Foo3) to the types notated in source code. If there's other solution, please let me know that too.
Just do this before calling cargo build.
export RUSTFLAGS="-Z save-analysis"
Update
Saved analysis data won't be loaded with default configuration of AnalysisHost. It's because CargoAnalysisLoader tries to load data from non-default location.
To workaround, just move save-analysis directory to proper location.
target/debug/deps/save-analysis
target/rls/debug/deps/save-analysis
Replace debug to release according to your build mode.

How to skip a library crate's examples depending on the target platform?

I have a Rust library crate which I only use on Linux, but I don't know of any reason it shouldn't work on Windows; however one of the examples is Unix-specific, so it the crate fails the build on AppVeyor.
The reason is that there's a Unix-only dependency (Termion) used by one of the examples, so when I used an AppVeyor template, it fails to build that dev-dependency.
So I made the dependency conditional:
[target.'cfg(unix)'.dev-dependencies]
termion = "1.0"
So far so good, but of course now that example fails on extern crate termion.
What I need is to just not build that example on non-Unix-like targets. I was hoping something like:
[[target.'cfg(unix)'.example]]
name = "foo"
would work, but I get:
warning: unused manifest key: target.cfg(unix).example
error: no example target named `foo`
Another promising way forward was Cargo's required-features, but as of writing it's apparently not in stable Cargo, which means that doesn't help me checking that it works on stable Rust on Windows.
The last option I can think of is to #[cfg(unix)] away most of the example's source, turning it into a stub on Windows, but I'd really like a cleaner way of doing it.
Is there some existing way of skipping an example on some unsupported targets that works with current stable Rust/Cargo?

Issue when replacing a crates dependency with a local version

So I am trying to serialize a struct using bincode following these instructions, and I was able to get that to work.
But then I wanted to serialize a struct with an IpAddr enum. Since IpAddr doesn't implement the Encodable trait needed, I downloaded the rustc_serialize crate from git and implemented encodable for IpAddr myself. I then changed my Cargo.toml file to:
[dependencies]
# rustc-serialize = "0.3"
byteorder = "0.3"
bincode = "0.4"
[dependencies.rustc-serialize]
path = "src/rustc-serialize-master"
But now, the same code from the struct I was using doesn't compile saying that
rustc_serialize::serialize::Encodable is not implemented for my struct even though i have #[derive(RustcEncodable)] above the struct.
Even when I get rid of the code I added to the local version of rustc_serialize, I still get that error.
I think it might be due to something being screwed up with the way bincode and a local rustc_serialize interact, but I'm not sure.
Please review the Cargo documentation on overriding dependencies:
To specify overrides, create a .cargo/config file in some ancestor of your project's directory (common places to put it is in the root of your code directory or in your home directory).
Inside that file, put this:
paths = ["/path/to/project/rand"]
Going deeper, you are likely running into issue 22750 - two different versions of a crate interacting leads to unhelpful error messages. When you add rustc-serialize to your dependencies, you aren't replacing the old version, you are adding a new one.
In general, this is a good feature. If my project relies on crates A and B and they both rely on crate Z but with different versions, Rust can handle that just fine. The problem arises when they re-export items from those crates.

Resources