Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does #[cfg(test)] do when placed at the top of lib.rs?

Tags:

rust

I'm writing a Rust library (generated from cargo) with unit tests.

I'd like to use the extern crate maplit in my unit tests to be able to use JavaScript-like hashmap literals. I don't want to use maplit in my library code.

maplit provides a macro that apparently must be activated using #[macro_use]. The only way I've been able to get this all working is to place this at the top of lib.rs:

#[cfg(test)] #[macro_use] extern crate maplit;

// my crate-specific stuff

At this point I realized I don't know what exactly #[cfg(test)] does. I'm using it in my tests. These are included with library code, as per the convention, like so:

// some library code

#[cfg(test)]
mod test {
  use super::*;
  // tests here
}

I had thought that the line #[cfg(test)] was marking what follows until the end of the file (or block?) as only applicable to the test configuration.

If so, then putting this directive at the top of lib.rs seems like a problem. Won't my entire library be dropped when I compile a distribution?

I've tried to find documentation on what exactly #[cfg(test)] does, but to no avail.

like image 875
Rich Apodaca Avatar asked Oct 31 '19 23:10

Rich Apodaca


People also ask

What does the fox say Meaning?

Speaking of the meaning of the song, Vegard characterizes it as coming from "a genuine wonder of what the fox says, because we didn't know". Although interpreted by some commentators as a reference to the furry fandom, the brothers have stated they did not know about its existence when producing "The Fox".

What does the fox say for real?

One of the most common fox vocalizations is a raspy bark. Scientists believe foxes use this barking sound to identify themselves and communicate with other foxes. Another eerie fox vocalization is a type of high-pitched howl that's almost like a scream.

How can I find a song by the sound?

On your phone, touch and hold the Home button or say "Hey Google." Ask "What's this song?" Play a song or hum, whistle, or sing the melody of a song. Hum, whistle, or sing: Google Assistant will identify potential matches for the song.

What Does the Fox Say video location?

Filmed at Glendora High School in Glendora, California.


1 Answers

#[....]

The above is a Rust Attribute which is like an annotation in other languages. For example; in Java we have @Annotation(....) for methods and classes. Unlike annotation the rust attribute can be an expression that follows the attribute syntax.

#[cfg(....)]

The above is a compiler configuration attribute. The cfg() is one of many built-in attributes.

#[cfg(test)]

The above tells the Rust compiler that the following code should only be compiled when the test configuration is active. You can have other configuration attributes like debug, windows or features.

#[cfg(test)] #[macro_use] extern crate maplit;

Is the same as

#[cfg(test)]
#[macro_use]
extern crate maplit;

Which tells the Rust compiler to only compile the next line if the test configuration is active, and the next line tells Rust to only use macros from the following crate.

If so, then putting this directive at the top of lib.rs seems like a problem. Won't my entire library be dropped when I compile a distribution?

The #[cfg(...)] attribute only applies the compiler condition upon the thing it is attached to.

When you place the attribute at the top of the file followed by a space. The attribute is attached to the current module or crate.

As shown here from the documentation example, the crate_type is applied to the entire file:

// General metadata applied to the enclosing module or crate.
#![crate_type = "lib"]

// A function marked as a unit test
#[test]
fn test_foo() {
    /* ... */
}

// A conditionally-compiled module
#[cfg(target_os = "linux")]
mod bar {
    /* ... */
}

// A lint attribute used to suppress a warning/error
#[allow(non_camel_case_types)]
type int8_t = i8;

// Inner attribute applies to the entire function.
fn some_unused_variables() {
  #![allow(unused_variables)]

  let x = ();
  let y = ();
  let z = ();
}
like image 188
Reactgular Avatar answered Nov 16 '22 02:11

Reactgular