Global feature gates in Cargo - rust

I would like to enable a feature gate for my entire Cargo project. For example, I would like #![feature(non_ascii_idents)] added to every source file. Is there a place to list them in Cargo.toml?

No, though you don't add feature gates to every source file; they are crate attributes. That is, you set them on the crate, not on every module.

There are two types of attributes:
file attributes (starting with #). They apply to the whole file only.
crate attributes (starting with #!). They apply to the whole crate at once.
What you want (#![feature(non_ascii_idents)]) is a crate attribute, so you need to place it once at the top of the crate's main file. That main file is usually:
src/main.rs for binaries
src/lib.rs for libraries

Related

Can I rename lib.rs to the crate name?

Right now I'm working on a project with multiple separate crates.
I would prefer lib.rs to be renamed to the crate's name itself, as when I open multiple at the same time it takes me an extra second to find the one I'm looking for, not a big deal just curious if it's possible or a good idea.
ne_log/lib.rs into: ne_log/ne_log.rs
Yes, in each Cargo.toml add a lib section with the desired path:
[lib]
path = "src/some_other_file.rs"
Read more here: Cargo Targets
As to whether its a good idea or not; it will make your file structure non-standard, but the option is available since there are plenty of non-standard workflows. Use your own discretion.

How can I have a shared Clippy configuration for all the crates in a workspace?

I have an application split into several crates. I want to deny or allow a specific lint in all crates. For example:
#![deny(clippy::print_stdout)]
It seems I have to add this to lib.rs in each of the crates.
There is an ticket with Cargo to allow configuring this somehow, but it has been open for several years with no clear conclusion.
Is there a workaround to avoid having these allow/deny/warn lines duplicated per crate?
One idea I had was to include! the lines by creating a clippy_config.rs at the workspace root, then in each crate's lib.rs adding
include!("../../clippy_config.rs");
However this fails with
error: an inner attribute is not permitted in this context
--> app/src/../../clippy_config.rs:1:1
|
1 | #![deny(clippy::print_stdout)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.
My other thought to use a macro also does not work for much the same reason.
Is there a simple way to do this, except writing an external script to modify the Rust files to automate the duplication? (as mentioned in this comment describing Embark Studio's setup).
Clippy offers 3 configuration modes:
Attributes: #[deny(clippy::print_stdout)]
Flags: -Dclippy::print-stdout
Configuration file: clippy.toml, though restricted to a subset of configurable lints.
For project-wide configuration, across crates, the configuration file is the best option if it works.
Otherwise, the second best (hacky) option is to use flags indirectly. That is, rather than specifying RUSTFLAGS=-Dclippy::print-stdout in front of your compiler invocation, you can let Cargo do it, and configure Cargo project-wide.
At the root of your project, create a .cargo/config.toml file with the following content:
[build]
rustflags = ["-Dclippy::print-stdout"]
Cargo will then pass this flag to clippy when it invokes it.
Note: in a workspace setting, .cargo/config.toml in individual crate folders is ignored when invoking Cargo from the root of the workspace, so best place this in the .cargo at the root.

Remove crate feature

I'm loading a crate in my project and this crate has a feature called object-pooling that is not thread safe. Someone suggested I remove this functionality from the crate but I don't know how to do that. Is there a special entry that I can add to my Cargo.toml file and disables features from dependencies?
The syntax in your CARGO.TOML is:
crate_name = {version="version_numer", features=[feature1, feature2]}
If you want or don't want to have a specific feature you can adapt the features list.
Check out the crates documentation or sourcecode if you want to know which features provide which functionality.
You can find the available features of your specific crate here:
https://github.com/brave/adblock-rust/blob/master/Cargo.toml#L86

How to make an item visible in my binary crate targets but not any other crates?

I would like to generate multiple binaries using a lot of the same common code. If I write everything in src/main.rs I can simply mark items at pub(crate) and access the code without exporting it. However if I put the binary in src/bin/foo.rs then I can not find a way to access this without marking everything pub. I would not like to mark everything pub not only because I don't want others to depend on it but also because it renders visibility checking ineffective.
The only workaround I have found is to put the file inside of the src directory then put a simple shim in bin/foo-bar.rs that just calls my_crate::bin_foo_bar::main(). This isn't very tidy and requires a bunch of overhead.
Inside your package you may define a single lib crate and multiple binary crates. If you declare a type inside your library crate as pub(crate) it will obviously unvisible from your binary crates. So revise the definitions. A package is not a crate, it is a package of crates. And pub(crate) types are only visible inside the crate they belong to.

Figure out code from what module is "use"d in a large rust project (servo)

I'm trying to read the code of servo. As an example, I'm looking at this code in layout_task.rs:
use url::Url;
..and I want to know which code this refers to (the answer is rust-url).
Per the Rust reference §6.1.2.2 Use declarations,
the paths contained in use items are relative to the crate root [...]
It is also possible to use self and super at the beginning of a use item to refer to the current and direct parent modules respectively.
All rules regarding accessing declared modules in use declarations apply to both module declarations and extern crate declarations.
The reference (§5 Crates and source files) does not explicitly say what a "crate root" is, but it does share that:
A crate contains a tree of nested module scopes. The top level of this tree is a module that is anonymous [...] The Rust compiler is always invoked with a single source file as input, and always produces a single output crate. The processing of that source file may result in other source files being loaded as modules.
So it seems that to find the crate root that the current file (layout_task.rs) belongs to, we need to figure out what source file rustc is invoked with when building the crate. With Cargo this is specified in Cargo.toml and defaults to src/lib.rs:
[lib]
path = "src/lib.rs"
In my case, here's Cargo.toml and the lib.rs has:
extern crate url;
pub mod layout_task;
So far so good. To find out what the extern crate refers to, we need to look at Cargo.toml again:
[dependencies.url]
version = "0.2"
The cargo docs claim that "Dependencies from crates.io are not declared with separate sections", but apparently they can be... So we look the package up on crates.io: https://crates.io/crates/url

Resources