What is current documentation tool for Rust? [duplicate] - rust

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.

Related

Project-specific override for Cargo

I primarily want to use Debian's Rust packages, rather than fetching some random code from the wider Internet (I'm old-fashioned, I know, let's not get into that part). To this end, my ~/.cargo/config.toml looks like
[net]
offline = true
[source]
[source.crates-io]
replace-with = "debian"
[source.debian]
directory = "/usr/share/cargo/registry"
This works great after I install the librust-*-dev packages that I desire. However, in some specific projects, I'd like to lift this rule and tell Cargo "hey, you can in fact go wild and get whatever you want from crates.io". According to the Cargo book, a project-specific /project/.cargo/config.toml should take precedence over my user one. Assume this project-specific .cargo/config.toml:
[net]
offline = false
[source]
[source.crates-io]
I'm still not able to cargo build a project with dependencies from outside of my replacement source. If for example, I make a Cargo.toml that depends on yew (a randomly chosen crate that I know isn't available in my replacement source) I get
$ cargo build
error: no matching package found
searched package name: `yew`
What am I misunderstanding about Cargo's sources, replacement and per-project overrides?
The answer suggested by #blackgreen is one possible workaround for the underlying problem until issues 10045 and 10057 (or a combination thereof) are solved. Another, perhaps slightly less ugly, workaround follows below for those who need it.
I ended up working around the problem using UnionFS (I guess the more modern OverlayFS should work well too).
I simply add
[source.crates-io]
replace-with = "union"
[source.union]
directory = "/home/gspr/.cargo-overlay/union-registry"
to my ~/.cargo/config.toml and then do
unionfs -o ro /usr/share/cargo/registry:/home/gspr/.cargo-overlay/local-registry /home/gspr/.cargo-overlay/union-registry
Now /home/gspr/.cargo-overlay/union-registry reflects the union of /usr/share/cargo/registry and /home/gspr/.cargo-overlay/local-registry, with priority to the former in case of conflicts.
So what goes in ~/.cargo-overlay/local-registry? Individual extra crates, in the same way as in Debian's /usr/share/cargo/registry. That is to say, directories named cratename-version as they are distributed by upstream – but with a single extra file, namely .cargo-checksum.json added to them. The content of that extra file can be extracted from the crates.io index as follows.
Suppose we have cloned the crates.io index into ~/.cargo-overlay/crates.io-index, i.e.
git clone https://github.com/rust-lang/crates.io-index.git ~/.cargo-overlay/crates.io-index
Then suppose we've extracted a crate foo at version 0.1.2 into ~/.cargo-overlay/local-registry/foo-0.1.2. We can generate the missing .cargo-checksum.json like so:
cd ~/.cargo-overlay
index_file=$(find crates.io-index -type f -name foo)
cksum=$(jq -r "select(.name == \"foo\" and .vers == \"0.1.2\" ) | .cksum" ${index_file})
jo package="${cksum}" files="{}" > local-registry/foo-0.1.2/.cargo-checksum.json
It looks as if you are suffering from this issue: https://github.com/rust-lang/cargo/issues/8687
You would like to unset a config key on a upper-level config.toml but this is not supported.
I've played a bit with the config, and the only way I got it to work was to overwrite in the project-local config.toml the properties that were set in the upper-level config.toml.
In your case your upper-level config.toml specifies replace-with, so you have to overwrite that. But you can't overwrite it with crates-io, which is the registry you want to use, because that is exactly the registry with the replace-with key.
So until the above issue gets acted upon, we have to, essentially, use a mirror, both in the config and as an actual registry to download from:
[net]
offline = false
[source]
[source.crates-io]
replace-with = "crates-io-mirror"
[source.crates-io-mirror]
registry = "https://gitlab.com/integer32llc/crates.io-index"
As we both tested, it seems it's not possible to reuse the normal crates.io registry url because that is already defined and will fail with:
error: source crates-io-mirror defines source registry https://github.com/rust-lang/crates.io-index, but that source is already defined by crates-io note: Sources are not allowed to be defined multiple times.
So instead the URL above is an actual mirror server of crates.io. Then you can run cargo build successfully in the local project.
The recently released Cargo 1.56 adds a feature that should let one do what my question asks for: patch tables can now be specified in a project-specific .cargo/config.toml, which means that [patch] stanzas can now be introduced outside of Cargo.toml. That should do the trick! I haven't yet verified this, as I am stuck with an older Cargo for a little while still.

Rust Amethyst Pong Tutorial Examples give "error: no example target named `pong_tutorial_01`"

I just cloned the github repository amethyst/amethyst, which is a game engine written in rust, in order to follow the docs and tutorials. The document at Amethyst documentation about the pong tutorial tells us that you can run examples using...
cargo run --example pong_tutorial_01 --features "vulkan"
... but when I try this, I get an error...
error: no example target named `pong_tutorial_01`
Now, this business of running code examples that are provided inside a larger project is new to me, but seems to be a proper part of Rust, and the behaviour is defined in the Cargo.toml(s) of the outer project and (I think) the example sub-projects within. But having read through some of the rust Cargo book here, about examples needing to live in the examples subdirectory, and there being ways to prevent their being discovered automatically (e.g. autoexamples = false) unless they are specifically configured another way, everything appears to be in order.
Does any smart person know why this doesn't work, without me learning every single detail of how to configure cargo? Thanks in advance.
ps
I'm running on Win 10. Rustup update is up to date. Other rust things work. Indeed, these examples work, if I delve all the way into their directories and run them with cargo run directly, so I don't think I have a language/toolchain configuration problem. I'm just interested as to why that particular command line doesn't work as advertised.
It looks like the examples were recently converted from from cargo examples to workspace members. They were largely disabled in this PR and then fixed up as standalone packages in this PR. The latter of which cites dependency management as the reason for the change. The documentation probably hasn't been updated accordingly.
You should be able to use -p/--package instead:
cargo run -p pong_tutorial_01 --features "vulkan"
For anyone else stumbling on this post, the above answer is correct for the main branch of the amethyst project.
However, the project currently has two important branches:
The v0.15.3 or stable branch, which is the most recent release on crates.io
The main or master branch, which is under heavy work to eventually release the next version of amethyst
It's important to note that the link given by op is to the stable book, which references v0.15.3. The examples can be run for that version by checking out the correct branch and running the command as the book says:
git checkout v0.15.3
cargo run --example pong_tutorial_01 --features "vulkan"
I would recommend following v0.15.3 for now, since it it well-documented. The main branch has yet to update most of the docs.

How do I compile Rust code without linking, i.e. produce object files?

Due to how the LGPL works, compiling Rust code to an object file without linking would be useful to be able to do. However, I cannot find any documentation on how to do this. I checked rustc's help section and searched, but couldn't find anything, which brings me to my question: How do I tell rustc to not link and produce object files that later can be linked?
Use the compiler flag --emit=obj.
cargo rustc -- --emit=obj
The compiled object files will be sitting in target/debug/deps.
See also:
How to pass rustc flags to cargo?

How to load Rust compiler plugins without modifying the source code?

Rust provides various ways to write plugins. To extend checks on Rust code, it allows developer to write Lint Plugins. A typical way to use the plugin is to add a line to the source code indicating the use of this plugin:
#![plugin(myplugin)]
You also need to edit the Cargo.toml file to include your plugin project in the dependencies section:
myplugin = {path = "/path/to/myproject"}
However, if you want to analyze big projects, these modifications seem to be troubling, I wonder if cargo build or rustc provides any way to load my plugins without modifying the source code.
rustc has a command-line parameter for loading additional plugins: -Z extra-plugins=<plugins>. However, this option also requires that the path to the compiled plugin library be passed to the compiler. This is done automatically if the plugin library is declared as a dependency in Cargo.toml. If it's not in Cargo.toml, then you can compile it independently and reference it manually with --extern my_plugin=/path/to/plugin.rlib, in addition to the -Z extra-plugins=<plugins> option.
There's another option. Clippy, a large collection of general lints for Rust, provides a program that can be invoked as cargo clippy. That program basically acts as a fake rustc, implementing a compiler frontend (using internal crates used by rustc) that loads Clippy directly into the compiler's plugin registry (for the main project only, not for the project's dependencies). You can see the code on GitHub (licensed under MPLv2). The advantage of this approach is that you don't have to give a path to the plugin, because the plugin is built in the frontend. This makes it very convenient to use for the plugin's users. The disadvantage is that such a program relies on unstable compiler internals. This means that your program can stop compiling at any time due to a breaking change in rustc's unstable API.

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