What is proc_macro2 vs. proc-macro2? - rust

Trying to learn procedural macros as part of internalizing Rust. I don't need competing crates. What is going on here?
proc-macro2:
https://crates.io/crates/proc-macro2
proc_macro2:
https://docs.rs/proc-macro2/latest/proc_macro2/
WTH is going on here? It's causing all sorts of issue trying to run "cargo upgrade" and somehow get cargo.toml and main.rs to agree on underscore vs dash. Seems very silly, what am I missing?

The crate name is with dash and that's how it needs to be specified in Cargo.toml.
But crate names with dashes become underscores for imports.
That's why docs.rs uses first dash - this is the crate name in crates.io - and second underscore - this is the crate name in Rust.

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.

What does :: (double colon) mean before an identifier?

This line is from Rust libc crate. What is the use of double colon here? I thought its bringing c_uint in the scope from the crate root but I can't find where its defined in the crate root.
pub type speed_t = ::c_uint;
https://doc.rust-lang.org/reference/paths.html#path-qualifiers
Paths can be denoted with various leading qualifiers to change the meaning of how it is resolved.
::
Paths starting with :: are considered to be global paths where the segments of the path start being resolved from the crate root. Each identifier in the path must resolve to an item.
So your idea was correct, it is resolving from the crate root.
I can't find where its defined in the crate root.
well libc doesn't in-and-of-itself define anything at the crate root, instead the crate root re-exports the content of the submodule matching the compilation target.
So on unix the "crate root" contains anything exposed by the fixed_width_ints and unix submodules. The former is not really useful for you, but the latter... does define a c_uint symbol.
This syntax works in libc because its compiled using the 2015 Edition of Rust. The Paths reference includes a note:
Edition Differences: In the 2015 Edition, the crate root contains a variety of different items, including external crates, default crates such as std and core, and items in the top level of the crate (including use imports).
Beginning with the 2018 Edition, paths starting with :: can only reference crates.
In 2015, the ::c_uint would find the re-exported type, whereas in 2018 it won't. There were a number of module resolution changes that are described with more detail in the Edition Guide.
You can test it out on the playground (you can change editions in the advanced options menu next to Debug and Stable).

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

What is a Rust systest?

I sometimes see that a Rust crate has a folder called systest. I guess that the name stands for "system test", but I can't find any documentation of this.
My questions are:
What is the purpose of a systest? Just testing that a crate compiles fine, or also testing that some code in another crate runs fine?
What are the rules to follow when writing a systest? Is it just a crate in a folder called systest?
Why does the lib.rs in systest/src seem to always include a file all.rs generated from build.rs?
systest is not a standard name used in Rust or Cargo. However, it is the name suggested by the documentation for ctest, which performs automated testing for FFI bindings. build.rs uses ctest to generate the all.rs file which contains the tests, and this is included from the main file.
According to the documentation, the tests generate include ensuring that all function signatures, constant values, struct layout/alignment, type size/alignment, etc., all match their C equivalent.

Multiple Rust source files for cargo

If I have multiple .rs files in the src directory of a Cargo package, what are the rules for visibility, importing, etc.?
Currently, any extra (i.e. not the file that is explicitly identified as the source for the executable in Cargo.toml) files are ignored.
What do I need to do to fix this?
There is nothing special about Cargo at all in this way. It’s all the perfectly normal Rust module system. If Cargo will be compiling src/lib.rs, that’s more or less equivalent to having executed rustc --crate-type lib src/lib.rs (there are more command line arguments in practice, but that’s the basics of it).
Other files are then used with mod, use and so forth. Files are not automatically imported or anything like that. This part is not documented very clearly yet; a couple of things that show briefly how to achieve things are http://rustbyexample.com/mod/split.html and http://doc.rust-lang.org/reference.html#modules, but any non-trivial code base will use them and so you can pick just about any code base to look at for examples.
It's hard to say what you're getting tripped up on from the info you shared. Here are three seemingly trivial things that I still had to refer to the documentaton to figure out:
First of all,
mod foo;
looks like a declaration, but it without arguments it is actually something like an include. So you use the same keyword both for declaring and including modules, i.e. there is no using:: keyword.
Second, modules themselves can be public or private. If you didn't add a pub keyword both on the function in question AND on the containing module, that may be tripping you up.
pub mod foo {pub fn bar();}
Third, there seems to be an implicit module added at the top of every file. This is confusing; the reference manual talks about a strict separation between file paths and names, and the module paths in your code, but that abstraction seems to be leaky here.
Note, Rust is still pre-1.0 (0.12) at the time of writing, at the module system and file paths are relatively high level, so don't be surprised if what I said may already wrong by the time you read this.
Files are implicitly included from your rust code.
For instance, if a file src/foo.rs pointed by path in a [lib] or [[bin]] section of your Cargo.toml contains:
mod bar;
It tells cargo to build src/bar.rs too, and include it.

Resources