Skip to content

Commit 46b83f4

Browse files
committed
Auto merge of #12159 - weihanglo:source-doc, r=epage
docs(source): doc comments for Source and its impls
2 parents 5cedce9 + a9d2c06 commit 46b83f4

File tree

4 files changed

+153
-81
lines changed

4 files changed

+153
-81
lines changed

src/cargo/core/source/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ pub trait Source {
6262

6363
/// Attempts to find the packages that match a dependency request.
6464
///
65+
/// Usually you should call [`Source::block_until_ready`] somewhere and
66+
/// wait until package informations become available. Otherwise any query
67+
/// may return a [`Poll::Pending`].
68+
///
6569
/// The `f` argument is expected to get called when any [`Summary`] becomes available.
6670
fn query(
6771
&mut self,
@@ -70,8 +74,8 @@ pub trait Source {
7074
f: &mut dyn FnMut(Summary),
7175
) -> Poll<CargoResult<()>>;
7276

73-
/// A helper function that collects and returns the result from
74-
/// [`Source::query`] as a list of [`Summary`] items when available.
77+
/// Gathers the result from [`Source::query`] as a list of [`Summary`] items
78+
/// when they become available.
7579
fn query_vec(&mut self, dep: &Dependency, kind: QueryKind) -> Poll<CargoResult<Vec<Summary>>> {
7680
let mut ret = Vec::new();
7781
self.query(dep, kind, &mut |s| ret.push(s)).map_ok(|_| ret)

src/cargo/core/source/source_id.rs

+93-71
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,31 @@ lazy_static::lazy_static! {
2020
}
2121

2222
/// Unique identifier for a source of packages.
23+
///
24+
/// Cargo uniquely identifies packages using [`PackageId`], a combination of the
25+
/// package name, version, and the code source. `SourceId` exactly represents
26+
/// the "code source" in `PackageId`. See [`SourceId::hash`] to learn what are
27+
/// taken into account for the uniqueness of a source.
28+
///
29+
/// `SourceId` is usually associated with an instance of [`Source`], which is
30+
/// supposed to provide a `SourceId` via [`Source::source_id`] method.
31+
///
32+
/// [`Source`]: super::Source
33+
/// [`Source::source_id`]: super::Source::source_id
34+
/// [`PackageId`]: super::super::PackageId
2335
#[derive(Clone, Copy, Eq, Debug)]
2436
pub struct SourceId {
2537
inner: &'static SourceIdInner,
2638
}
2739

40+
/// The interned version of [`SourceId`] to avoid excessive clones and borrows.
41+
/// Values are cached in `SOURCE_ID_CACHE` once created.
2842
#[derive(Eq, Clone, Debug)]
2943
struct SourceIdInner {
3044
/// The source URL.
3145
url: Url,
32-
/// The canonical version of the above url
46+
/// The canonical version of the above url. See [`CanonicalUrl`] to learn
47+
/// why it is needed and how it normalizes a URL.
3348
canonical_url: CanonicalUrl,
3449
/// The source kind.
3550
kind: SourceKind,
@@ -45,8 +60,8 @@ struct SourceIdInner {
4560
alt_registry_key: Option<String>,
4661
}
4762

48-
/// The possible kinds of code source. Along with `SourceIdInner`, this fully defines the
49-
/// source.
63+
/// The possible kinds of code source.
64+
/// Along with [`SourceIdInner`], this fully defines the source.
5065
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
5166
enum SourceKind {
5267
/// A git repository.
@@ -70,7 +85,8 @@ pub enum GitReference {
7085
Tag(String),
7186
/// From a branch.
7287
Branch(String),
73-
/// From a specific revision.
88+
/// From a specific revision. Can be a commit hash (either short or full),
89+
/// or a named reference like `refs/pull/493/head`.
7490
Rev(String),
7591
/// The default branch of the repository, the reference named `HEAD`.
7692
DefaultBranch,
@@ -100,6 +116,7 @@ impl SourceId {
100116
Ok(source_id)
101117
}
102118

119+
/// Interns the value and returns the wrapped type.
103120
fn wrap(inner: SourceIdInner) -> SourceId {
104121
let mut cache = SOURCE_ID_CACHE.lock().unwrap();
105122
let inner = cache.get(&inner).cloned().unwrap_or_else(|| {
@@ -172,7 +189,7 @@ impl SourceId {
172189
}
173190
}
174191

175-
/// A view of the `SourceId` that can be `Display`ed as a URL.
192+
/// A view of the [`SourceId`] that can be `Display`ed as a URL.
176193
pub fn as_url(&self) -> SourceIdAsUrl<'_> {
177194
SourceIdAsUrl {
178195
inner: &*self.inner,
@@ -208,7 +225,7 @@ impl SourceId {
208225
SourceId::new(kind, url.to_owned(), Some(name))
209226
}
210227

211-
/// Creates a SourceId from a local registry path.
228+
/// Creates a `SourceId` from a local registry path.
212229
pub fn for_local_registry(path: &Path) -> CargoResult<SourceId> {
213230
let url = path.into_url()?;
214231
SourceId::new(SourceKind::LocalRegistry, url, None)
@@ -287,6 +304,7 @@ impl SourceId {
287304
&self.inner.canonical_url
288305
}
289306

307+
/// Displays the text "crates.io index" for Cargo shell status output.
290308
pub fn display_index(self) -> String {
291309
if self.is_crates_io() {
292310
format!("{} index", CRATES_IO_DOMAIN)
@@ -295,6 +313,7 @@ impl SourceId {
295313
}
296314
}
297315

316+
/// Displays the name of a registry if it has one. Otherwise just the URL.
298317
pub fn display_registry_name(self) -> String {
299318
if self.is_crates_io() {
300319
CRATES_IO_REGISTRY.to_string()
@@ -360,6 +379,8 @@ impl SourceId {
360379
}
361380

362381
/// Creates an implementation of `Source` corresponding to this ID.
382+
///
383+
/// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked.
363384
pub fn load<'a>(
364385
self,
365386
config: &'a Config,
@@ -434,7 +455,7 @@ impl SourceId {
434455
/// Hashes `self`.
435456
///
436457
/// For paths, remove the workspace prefix so the same source will give the
437-
/// same hash in different locations.
458+
/// same hash in different locations, helping reproducible builds.
438459
pub fn stable_hash<S: hash::Hasher>(self, workspace: &Path, into: &mut S) {
439460
if self.is_path() {
440461
if let Ok(p) = self
@@ -563,9 +584,9 @@ impl fmt::Display for SourceId {
563584
}
564585
}
565586

566-
// The hash of SourceId is used in the name of some Cargo folders, so shouldn't
567-
// vary. `as_str` gives the serialisation of a url (which has a spec) and so
568-
// insulates against possible changes in how the url crate does hashing.
587+
/// The hash of SourceId is used in the name of some Cargo folders, so shouldn't
588+
/// vary. `as_str` gives the serialisation of a url (which has a spec) and so
589+
/// insulates against possible changes in how the url crate does hashing.
569590
impl Hash for SourceId {
570591
fn hash<S: hash::Hasher>(&self, into: &mut S) {
571592
self.inner.kind.hash(into);
@@ -576,89 +597,90 @@ impl Hash for SourceId {
576597
}
577598
}
578599

600+
/// The hash of `SourceIdInner` is used to retrieve its interned value from
601+
/// `SOURCE_ID_CACHE`. We only care about fields that make `SourceIdInner`
602+
/// unique. Optional fields not affecting the uniqueness must be excluded,
603+
/// such as [`name`] and [`alt_registry_key`]. That's why this is not derived.
604+
///
605+
/// [`name`]: SourceIdInner::name
606+
/// [`alt_registry_key`]: SourceIdInner::alt_registry_key
579607
impl Hash for SourceIdInner {
580-
/// The hash of `SourceIdInner` is used to retrieve its interned value. We
581-
/// only care about fields that make `SourceIdInner` unique, which are:
582-
///
583-
/// - `kind`
584-
/// - `precise`
585-
/// - `canonical_url`
586608
fn hash<S: hash::Hasher>(&self, into: &mut S) {
587609
self.kind.hash(into);
588610
self.precise.hash(into);
589611
self.canonical_url.hash(into);
590612
}
591613
}
592614

615+
/// This implementation must be synced with [`SourceIdInner::hash`].
593616
impl PartialEq for SourceIdInner {
594-
/// This implementation must be synced with [`SourceIdInner::hash`].
595617
fn eq(&self, other: &Self) -> bool {
596618
self.kind == other.kind
597619
&& self.precise == other.precise
598620
&& self.canonical_url == other.canonical_url
599621
}
600622
}
601623

602-
// forward to `Ord`
624+
/// Forwards to `Ord`
603625
impl PartialOrd for SourceKind {
604626
fn partial_cmp(&self, other: &SourceKind) -> Option<Ordering> {
605627
Some(self.cmp(other))
606628
}
607629
}
608630

609-
// Note that this is specifically not derived on `SourceKind` although the
610-
// implementation here is very similar to what it might look like if it were
611-
// otherwise derived.
612-
//
613-
// The reason for this is somewhat obtuse. First of all the hash value of
614-
// `SourceKind` makes its way into `~/.cargo/registry/index/github.com-XXXX`
615-
// which means that changes to the hash means that all Rust users need to
616-
// redownload the crates.io index and all their crates. If possible we strive to
617-
// not change this to make this redownloading behavior happen as little as
618-
// possible. How is this connected to `Ord` you might ask? That's a good
619-
// question!
620-
//
621-
// Since the beginning of time `SourceKind` has had `#[derive(Hash)]`. It for
622-
// the longest time *also* derived the `Ord` and `PartialOrd` traits. In #8522,
623-
// however, the implementation of `Ord` changed. This handwritten implementation
624-
// forgot to sync itself with the originally derived implementation, namely
625-
// placing git dependencies as sorted after all other dependencies instead of
626-
// first as before.
627-
//
628-
// This regression in #8522 (Rust 1.47) went unnoticed. When we switched back
629-
// to a derived implementation in #9133 (Rust 1.52 beta) we only then ironically
630-
// saw an issue (#9334). In #9334 it was observed that stable Rust at the time
631-
// (1.51) was sorting git dependencies last, whereas Rust 1.52 beta would sort
632-
// git dependencies first. This is because the `PartialOrd` implementation in
633-
// 1.51 used #8522, the buggy implementation, which put git deps last. In 1.52
634-
// it was (unknowingly) restored to the pre-1.47 behavior with git dependencies
635-
// first.
636-
//
637-
// Because the breakage was only witnessed after the original breakage, this
638-
// trait implementation is preserving the "broken" behavior. Put a different way:
639-
//
640-
// * Rust pre-1.47 sorted git deps first.
641-
// * Rust 1.47 to Rust 1.51 sorted git deps last, a breaking change (#8522) that
642-
// was never noticed.
643-
// * Rust 1.52 restored the pre-1.47 behavior (#9133, without knowing it did
644-
// so), and breakage was witnessed by actual users due to difference with
645-
// 1.51.
646-
// * Rust 1.52 (the source as it lives now) was fixed to match the 1.47-1.51
647-
// behavior (#9383), which is now considered intentionally breaking from the
648-
// pre-1.47 behavior.
649-
//
650-
// Note that this was all discovered when Rust 1.53 was in nightly and 1.52 was
651-
// in beta. #9133 was in both beta and nightly at the time of discovery. For
652-
// 1.52 #9383 reverted #9133, meaning 1.52 is the same as 1.51. On nightly
653-
// (1.53) #9397 was created to fix the regression introduced by #9133 relative
654-
// to the current stable (1.51).
655-
//
656-
// That's all a long winded way of saying "it's weird that git deps hash first
657-
// and are sorted last, but it's the way it is right now". The author of this
658-
// comment chose to handwrite the `Ord` implementation instead of the `Hash`
659-
// implementation, but it's only required that at most one of them is
660-
// hand-written because the other can be derived. Perhaps one day in
661-
// the future someone can figure out how to remove this behavior.
631+
/// Note that this is specifically not derived on `SourceKind` although the
632+
/// implementation here is very similar to what it might look like if it were
633+
/// otherwise derived.
634+
///
635+
/// The reason for this is somewhat obtuse. First of all the hash value of
636+
/// `SourceKind` makes its way into `~/.cargo/registry/index/github.com-XXXX`
637+
/// which means that changes to the hash means that all Rust users need to
638+
/// redownload the crates.io index and all their crates. If possible we strive
639+
/// to not change this to make this redownloading behavior happen as little as
640+
/// possible. How is this connected to `Ord` you might ask? That's a good
641+
/// question!
642+
///
643+
/// Since the beginning of time `SourceKind` has had `#[derive(Hash)]`. It for
644+
/// the longest time *also* derived the `Ord` and `PartialOrd` traits. In #8522,
645+
/// however, the implementation of `Ord` changed. This handwritten implementation
646+
/// forgot to sync itself with the originally derived implementation, namely
647+
/// placing git dependencies as sorted after all other dependencies instead of
648+
/// first as before.
649+
///
650+
/// This regression in #8522 (Rust 1.47) went unnoticed. When we switched back
651+
/// to a derived implementation in #9133 (Rust 1.52 beta) we only then ironically
652+
/// saw an issue (#9334). In #9334 it was observed that stable Rust at the time
653+
/// (1.51) was sorting git dependencies last, whereas Rust 1.52 beta would sort
654+
/// git dependencies first. This is because the `PartialOrd` implementation in
655+
/// 1.51 used #8522, the buggy implementation, which put git deps last. In 1.52
656+
/// it was (unknowingly) restored to the pre-1.47 behavior with git dependencies
657+
/// first.
658+
///
659+
/// Because the breakage was only witnessed after the original breakage, this
660+
/// trait implementation is preserving the "broken" behavior. Put a different way:
661+
///
662+
/// * Rust pre-1.47 sorted git deps first.
663+
/// * Rust 1.47 to Rust 1.51 sorted git deps last, a breaking change (#8522) that
664+
/// was never noticed.
665+
/// * Rust 1.52 restored the pre-1.47 behavior (#9133, without knowing it did
666+
/// so), and breakage was witnessed by actual users due to difference with
667+
/// 1.51.
668+
/// * Rust 1.52 (the source as it lives now) was fixed to match the 1.47-1.51
669+
/// behavior (#9383), which is now considered intentionally breaking from the
670+
/// pre-1.47 behavior.
671+
///
672+
/// Note that this was all discovered when Rust 1.53 was in nightly and 1.52 was
673+
/// in beta. #9133 was in both beta and nightly at the time of discovery. For
674+
/// 1.52 #9383 reverted #9133, meaning 1.52 is the same as 1.51. On nightly
675+
/// (1.53) #9397 was created to fix the regression introduced by #9133 relative
676+
/// to the current stable (1.51).
677+
///
678+
/// That's all a long winded way of saying "it's weird that git deps hash first
679+
/// and are sorted last, but it's the way it is right now". The author of this
680+
/// comment chose to handwrite the `Ord` implementation instead of the `Hash`
681+
/// implementation, but it's only required that at most one of them is
682+
/// hand-written because the other can be derived. Perhaps one day in
683+
/// the future someone can figure out how to remove this behavior.
662684
impl Ord for SourceKind {
663685
fn cmp(&self, other: &SourceKind) -> Ordering {
664686
match (self, other) {

src/cargo/sources/config.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Implementation of configuration for various sources
1+
//! Implementation of configuration for various sources.
22
//!
33
//! This module will parse the various `source.*` TOML configuration keys into a
44
//! structure usable by Cargo itself. Currently this is primarily used to map
@@ -14,11 +14,12 @@ use log::debug;
1414
use std::collections::{HashMap, HashSet};
1515
use url::Url;
1616

17+
/// Represents the entire `[source]` table in Cargo configuration.
1718
#[derive(Clone)]
1819
pub struct SourceConfigMap<'cfg> {
1920
/// Mapping of source name to the toml configuration.
2021
cfgs: HashMap<String, SourceConfig>,
21-
/// Mapping of `SourceId` to the source name.
22+
/// Mapping of [`SourceId`] to the source name.
2223
id2name: HashMap<SourceId, String>,
2324
config: &'cfg Config,
2425
}
@@ -67,6 +68,8 @@ struct SourceConfig {
6768
}
6869

6970
impl<'cfg> SourceConfigMap<'cfg> {
71+
/// Like [`SourceConfigMap::empty`] but includes sources from source
72+
/// replacement configurations.
7073
pub fn new(config: &'cfg Config) -> CargoResult<SourceConfigMap<'cfg>> {
7174
let mut base = SourceConfigMap::empty(config)?;
7275
let sources: Option<HashMap<String, SourceConfigDef>> = config.get("source")?;
@@ -78,6 +81,8 @@ impl<'cfg> SourceConfigMap<'cfg> {
7881
Ok(base)
7982
}
8083

84+
/// Creates the default set of sources that doesn't take `[source]`
85+
/// replacement into account.
8186
pub fn empty(config: &'cfg Config) -> CargoResult<SourceConfigMap<'cfg>> {
8287
let mut base = SourceConfigMap {
8388
cfgs: HashMap::new(),
@@ -112,11 +117,14 @@ impl<'cfg> SourceConfigMap<'cfg> {
112117
Ok(base)
113118
}
114119

120+
/// Returns the `Config` this source config map is associated with.
115121
pub fn config(&self) -> &'cfg Config {
116122
self.config
117123
}
118124

119-
/// Get the `Source` for a given `SourceId`.
125+
/// Gets the [`Source`] for a given [`SourceId`].
126+
///
127+
/// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked.
120128
pub fn load(
121129
&self,
122130
id: SourceId,
@@ -208,6 +216,7 @@ restore the source replacement configuration to continue the build
208216
Ok(Box::new(ReplacedSource::new(id, new_id, new_src)))
209217
}
210218

219+
/// Adds a source config with an associated name.
211220
fn add(&mut self, name: &str, cfg: SourceConfig) -> CargoResult<()> {
212221
if let Some(old_name) = self.id2name.insert(cfg.id, name.to_string()) {
213222
// The user is allowed to redefine the built-in crates-io
@@ -226,6 +235,7 @@ restore the source replacement configuration to continue the build
226235
Ok(())
227236
}
228237

238+
/// Adds a source config from TOML definition.
229239
fn add_config(&mut self, name: String, def: SourceConfigDef) -> CargoResult<()> {
230240
let mut srcs = Vec::new();
231241
if let Some(registry) = def.registry {

0 commit comments

Comments
 (0)