//! ```
//! # #[cfg(feature = "std")]
//! # {
//! use std::{process::ExitCode, str};
//!
//! fn main() -> ExitCode {
//! let bytes = b"Hello, world!";
//! if str::from_utf8(bytes).is_ok() {
//! ExitCode::SUCCESS
//! } else {
//! ExitCode::FAILURE
//! }
//! }
//! # }
//!
//! #[cfg(not(feature = "std"))]
//! fn main() {}
//! ```
...
When I ran the above on the nightly, the error in the title occurred. This compiled fine on the latest stable. When I wrote code similar to this as normal code, a compilation error occurred even on the latest stable.
Is this compilation error occurring because the above doctests is incorrect, or is this occurring because of a bug on the nightly?
I don't know why it would compile on stable, but the code is not valid rust.
you cannot have top level blocks. in regular code, you can use the cfg-if
crate, but I don't think it could be used in doctests.
as a workaround, you can put the conditional code in a mod
or fn
, and call it based on the cfg features, example:
#[cfg(not(feature = "std"))]
pub fn test_main() {
println!("hello, no std world!");
}
#[cfg(feature = "std")]
pub fn test_main() {
println!("hello, std world");
}
fn main() {
test_main();
}
EDIT:
the above wording may be confusing. what I meant to say is, you can only put #[cfg()]
on items, rust have items like mod
or fn
, but a block at top level is not a valid item. doctest code is typically not very long, you can just put them in a single function, like fn main()
, but if you want to organize the snippet as mulpitle functions, but you don't want to add #[cfg()]
for all of them, you can put them in a mod
, which can be gated with cfg features. a better example would use a mod
like this;
#[cfg(not(feature = "std"))]
pub fn main() {
println!("hello, no std world!");
}
#[cfg(feature = "std")]
fn main() {
__with_std::main()
}
#[cfg(feature = "std")]
mod __with_std {
use xyz::abc;
fn foo() {}
fn bar() {}
pub fn main() {
foo();
bar();
}
}
2 Likes