@@ -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 ) ]
2436pub 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 ) ]
2943struct 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 ) ]
5166enum 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.
569590impl 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
579607impl 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`].
593616impl 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`
603625impl 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.
662684impl Ord for SourceKind {
663685 fn cmp ( & self , other : & SourceKind ) -> Ordering {
664686 match ( self , other) {
0 commit comments