Skip to content

Commit

Permalink
Auto merge of #11870 - epage:registry, r=Eh2406
Browse files Browse the repository at this point in the history
docs(contrib): Move higher level resolver docs into doc comments

This is a follow up to #11809.

I chose `ops::resolve` for most of the old documentation as this because the docs cover the
higher level details that include it, like `Cargo.lock` file, while
`core::resolver` is more of the algorithm.
  • Loading branch information
bors committed Mar 21, 2023
2 parents ed42a0d + bd5e1a5 commit 15d0909
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 97 deletions.
11 changes: 11 additions & 0 deletions src/cargo/core/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@
//! everything to bail out immediately and return success, and only if *nothing*
//! works do we actually return an error up the stack.
//!
//! Resolution is currently performed twice
//! 1. With all features enabled (this is what gets saved to `Cargo.lock`)
//! 2. With only the specific features the user selected on the command-line. Ideally this
//! run will get removed in the future when transitioning to the new feature resolver.
//!
//! A new feature-specific resolver was added in 2020 which adds more sophisticated feature
//! resolution. It is located in the [`features`] module. The original dependency resolver still
//! performs feature unification, as it can help reduce the dependencies it has to consider during
//! resolution (rather than assuming every optional dependency of every package is enabled).
//! Checking if a feature is enabled must go through the new feature resolver.
//!
//! ## Performance
//!
//! Note that this is a relatively performance-critical portion of Cargo. The
Expand Down
5 changes: 3 additions & 2 deletions src/cargo/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
//! This is the entry point for all the compilation commands. This is a
//! good place to start if you want to follow how compilation starts and
//! flows to completion.
//! - [`core::resolver`]:
//! This is the dependency and feature resolvers.
//! - [`ops::resolve`]:
//! Top-level API for dependency and feature resolver (e.g. [`ops::resolve_ws`])
//! - [`core::resolver`]: The core algorithm
//! - [`core::compiler`]:
//! This is the code responsible for running `rustc` and `rustdoc`.
//! - [`core::compiler::build_context`]:
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ mod common_for_install_and_uninstall;
mod fix;
pub(crate) mod lockfile;
pub(crate) mod registry;
mod resolve;
pub(crate) mod resolve;
pub mod tree;
mod vendor;

Expand Down
53 changes: 49 additions & 4 deletions src/cargo/ops/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,59 @@
//! High-level APIs for executing the resolver.
//!
//! This module provides functions for running the resolver given a workspace.
//! This module provides functions for running the resolver given a workspace, including loading
//! the `Cargo.lock` file and checkinf if it needs updating.
//!
//! There are roughly 3 main functions:
//!
//! - `resolve_ws`: A simple, high-level function with no options.
//! - `resolve_ws_with_opts`: A medium-level function with options like
//! - [`resolve_ws`]: A simple, high-level function with no options.
//! - [`resolve_ws_with_opts`]: A medium-level function with options like
//! user-provided features. This is the most appropriate function to use in
//! most cases.
//! - `resolve_with_previous`: A low-level function for running the resolver,
//! - [`resolve_with_previous`]: A low-level function for running the resolver,
//! providing the most power and flexibility.
//!
//! ### Data Structures
//!
//! - [`Workspace`]:
//! Usually created by [`crate::util::command_prelude::ArgMatchesExt::workspace`] which discovers the root of the
//! workspace, and loads all the workspace members as a [`Package`] object
//! - [`Package`]
//! Corresponds with `Cargo.toml` manifest (deserialized as [`Manifest`]) and its associated files.
//! - [`Target`]s are crates such as the library, binaries, integration test, or examples.
//! They are what is actually compiled by `rustc`.
//! Each `Target` defines a crate root, like `src/lib.rs` or `examples/foo.rs`.
//! - [`PackageId`] --- A unique identifier for a package.
//! - [`PackageRegistry`]:
//! The primary interface for how the dependency
//! resolver finds packages. It contains the `SourceMap`, and handles things
//! like the `[patch]` table. The dependency resolver
//! sends a query to the `PackageRegistry` to "get me all packages that match
//! this dependency declaration". The `Registry` trait provides a generic interface
//! to the `PackageRegistry`, but this is only used for providing an alternate
//! implementation of the `PackageRegistry` for testing.
//! - [`SourceMap`]: Map of all available sources.
//! - [`Source`]: An abstraction for something that can fetch packages (a remote
//! registry, a git repo, the local filesystem, etc.). Check out the [source
//! implementations] for all the details about registries, indexes, git
//! dependencies, etc.
//! * [`SourceId`]: A unique identifier for a source.
//! - [`Summary`]: A of a [`Manifest`], and is essentially
//! the information that can be found in a registry index. Queries against the
//! `PackageRegistry` yields a `Summary`. The resolver uses the summary
//! information to build the dependency graph.
//! - [`PackageSet`] --- Contains all of the `Package` objects. This works with the
//! [`Downloads`] struct to coordinate downloading packages. It has a reference
//! to the `SourceMap` to get the `Source` objects which tell the `Downloads`
//! struct which URLs to fetch.
//!
//! [`Package`]: crate::core::package
//! [`Target`]: crate::core::Target
//! [`Manifest`]: crate::core::Manifest
//! [`Source`]: crate::core::Source
//! [`SourceMap`]: crate::core::SourceMap
//! [`PackageRegistry`]: crate::core::registry::PackageRegistry
//! [source implementations]: crate::sources
//! [`Downloads`]: crate::core::package::Downloads

use crate::core::compiler::{CompileKind, RustcTargetData};
use crate::core::registry::{LockedPatchDependency, PackageRegistry};
Expand Down
91 changes: 1 addition & 90 deletions src/doc/contrib/src/architecture/packages.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,3 @@
# Packages and Resolution

## Workspaces

The [`Workspace`] object is usually created very early by calling the
[`workspace`][ws-method] helper method. This discovers the root of the
workspace, and loads all the workspace members as a [`Package`] object. Each
package corresponds to a single `Cargo.toml` (which is deserialized into a
[`Manifest`]), and may define several [`Target`]s, such as the library,
binaries, integration test or examples. Targets are crates (each target
defines a crate root, like `src/lib.rs` or `examples/foo.rs`) and are what is
actually compiled by `rustc`.

## Packages and Sources

There are several data structures that are important to understand how
packages are found and loaded:

* [`Package`] --- A package, which is a `Cargo.toml` manifest and its associated
source files.
* [`PackageId`] --- A unique identifier for a package.
* [`Source`] --- An abstraction for something that can fetch packages (a remote
registry, a git repo, the local filesystem, etc.). Check out the [source
implementations] for all the details about registries, indexes, git
dependencies, etc.
* [`SourceId`] --- A unique identifier for a source.
* [`SourceMap`] --- Map of all available sources.
* [`PackageRegistry`] --- This is the main interface for how the dependency
resolver finds packages. It contains the `SourceMap`, and handles things
like the `[patch]` table. The `Registry` trait provides a generic interface
to the `PackageRegistry`, but this is only used for providing an alternate
implementation of the `PackageRegistry` for testing. The dependency resolver
sends a query to the `PackageRegistry` to "get me all packages that match
this dependency declaration".
* [`Summary`] --- A summary is a subset of a [`Manifest`], and is essentially
the information that can be found in a registry index. Queries against the
`PackageRegistry` yields a `Summary`. The resolver uses the summary
information to build the dependency graph.
* [`PackageSet`] --- Contains all of the `Package` objects. This works with the
[`Downloads`] struct to coordinate downloading packages. It has a reference
to the `SourceMap` to get the `Source` objects which tell the `Downloads`
struct which URLs to fetch.

All of these come together in the [`ops::resolve`] module. This module
contains the primary functions for performing resolution (described below). It
also handles downloading of packages. It is essentially where all of the data
structures above come together.

## Resolver

[`Resolve`] is the representation of a directed graph of package dependencies,
which uses [`PackageId`]s for nodes. This is the data structure that is saved
to the `Cargo.lock` file. If there is no lock file, Cargo constructs a resolve
by finding a graph of packages which matches declared dependency specification
according to SemVer.

[`ops::resolve`] is the front-end for creating a `Resolve`. It handles loading
the `Cargo.lock` file, checking if it needs updating, etc.

Resolution is currently performed twice. It is performed once with all
features enabled. This is the resolve that gets saved to `Cargo.lock`. It then
runs again with only the specific features the user selected on the
command-line. Ideally this second run will get removed in the future when
transitioning to the new feature resolver.

### Feature resolver

A new feature-specific resolver was added in 2020 which adds more
sophisticated feature resolution. It is located in the [`resolver::features`]
module. The original dependency resolver still performs feature unification,
as it can help reduce the dependencies it has to consider during resolution
(rather than assuming every optional dependency of every package is enabled).
Checking if a feature is enabled must go through the new feature resolver.


[`Workspace`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/workspace.rs
[ws-method]: https://github.com/rust-lang/cargo/blob/e4b65bdc80f2a293447f2f6a808fa7c84bf9a357/src/cargo/util/command_prelude.rs#L298-L318
[`Package`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/package.rs
[`Target`]: https://github.com/rust-lang/cargo/blob/e4b65bdc80f2a293447f2f6a808fa7c84bf9a357/src/cargo/core/manifest.rs#L181-L206
[`Manifest`]: https://github.com/rust-lang/cargo/blob/e4b65bdc80f2a293447f2f6a808fa7c84bf9a357/src/cargo/core/manifest.rs#L27-L51
[`Source`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/source/mod.rs
[`SourceId`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/source/source_id.rs
[`SourceMap`]: https://github.com/rust-lang/cargo/blob/e4b65bdc80f2a293447f2f6a808fa7c84bf9a357/src/cargo/core/source/mod.rs#L245-L249
[`PackageRegistry`]: https://github.com/rust-lang/cargo/blob/e4b65bdc80f2a293447f2f6a808fa7c84bf9a357/src/cargo/core/registry.rs#L36-L81
[`ops::resolve`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/ops/resolve.rs
[`resolver::features`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/resolver/features.rs#L259
[source implementations]: https://github.com/rust-lang/cargo/tree/master/src/cargo/sources
[`PackageId`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/package_id.rs
[`Summary`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/summary.rs
[`PackageSet`]: https://github.com/rust-lang/cargo/blob/e4b65bdc80f2a293447f2f6a808fa7c84bf9a357/src/cargo/core/package.rs#L283-L296
[`Downloads`]: https://github.com/rust-lang/cargo/blob/e4b65bdc80f2a293447f2f6a808fa7c84bf9a357/src/cargo/core/package.rs#L298-L352
[`Resolve`]: https://github.com/rust-lang/cargo/blob/master/src/cargo/core/resolver/resolve.rs
See [nightly docs](https://doc.rust-lang.org/nightly/nightly-rustc/cargo/index.html)

0 comments on commit 15d0909

Please sign in to comment.