@@ -20,16 +20,31 @@ lazy_static::lazy_static! {
20
20
}
21
21
22
22
/// 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
23
35
#[ derive( Clone , Copy , Eq , Debug ) ]
24
36
pub struct SourceId {
25
37
inner : & ' static SourceIdInner ,
26
38
}
27
39
40
+ /// The interned version of [`SourceId`] to avoid excessive clones and borrows.
41
+ /// Values are cached in `SOURCE_ID_CACHE` once created.
28
42
#[ derive( Eq , Clone , Debug ) ]
29
43
struct SourceIdInner {
30
44
/// The source URL.
31
45
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.
33
48
canonical_url : CanonicalUrl ,
34
49
/// The source kind.
35
50
kind : SourceKind ,
@@ -45,8 +60,8 @@ struct SourceIdInner {
45
60
alt_registry_key : Option < String > ,
46
61
}
47
62
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.
50
65
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
51
66
enum SourceKind {
52
67
/// A git repository.
@@ -70,7 +85,8 @@ pub enum GitReference {
70
85
Tag ( String ) ,
71
86
/// From a branch.
72
87
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`.
74
90
Rev ( String ) ,
75
91
/// The default branch of the repository, the reference named `HEAD`.
76
92
DefaultBranch ,
@@ -100,6 +116,7 @@ impl SourceId {
100
116
Ok ( source_id)
101
117
}
102
118
119
+ /// Interns the value and returns the wrapped type.
103
120
fn wrap ( inner : SourceIdInner ) -> SourceId {
104
121
let mut cache = SOURCE_ID_CACHE . lock ( ) . unwrap ( ) ;
105
122
let inner = cache. get ( & inner) . cloned ( ) . unwrap_or_else ( || {
@@ -172,7 +189,7 @@ impl SourceId {
172
189
}
173
190
}
174
191
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.
176
193
pub fn as_url ( & self ) -> SourceIdAsUrl < ' _ > {
177
194
SourceIdAsUrl {
178
195
inner : & * self . inner ,
@@ -208,7 +225,7 @@ impl SourceId {
208
225
SourceId :: new ( kind, url. to_owned ( ) , Some ( name) )
209
226
}
210
227
211
- /// Creates a SourceId from a local registry path.
228
+ /// Creates a ` SourceId` from a local registry path.
212
229
pub fn for_local_registry ( path : & Path ) -> CargoResult < SourceId > {
213
230
let url = path. into_url ( ) ?;
214
231
SourceId :: new ( SourceKind :: LocalRegistry , url, None )
@@ -287,6 +304,7 @@ impl SourceId {
287
304
& self . inner . canonical_url
288
305
}
289
306
307
+ /// Displays the text "crates.io index" for Cargo shell status output.
290
308
pub fn display_index ( self ) -> String {
291
309
if self . is_crates_io ( ) {
292
310
format ! ( "{} index" , CRATES_IO_DOMAIN )
@@ -295,6 +313,7 @@ impl SourceId {
295
313
}
296
314
}
297
315
316
+ /// Displays the name of a registry if it has one. Otherwise just the URL.
298
317
pub fn display_registry_name ( self ) -> String {
299
318
if self . is_crates_io ( ) {
300
319
CRATES_IO_REGISTRY . to_string ( )
@@ -360,6 +379,8 @@ impl SourceId {
360
379
}
361
380
362
381
/// Creates an implementation of `Source` corresponding to this ID.
382
+ ///
383
+ /// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked.
363
384
pub fn load < ' a > (
364
385
self ,
365
386
config : & ' a Config ,
@@ -434,7 +455,7 @@ impl SourceId {
434
455
/// Hashes `self`.
435
456
///
436
457
/// 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 .
438
459
pub fn stable_hash < S : hash:: Hasher > ( self , workspace : & Path , into : & mut S ) {
439
460
if self . is_path ( ) {
440
461
if let Ok ( p) = self
@@ -563,9 +584,9 @@ impl fmt::Display for SourceId {
563
584
}
564
585
}
565
586
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.
569
590
impl Hash for SourceId {
570
591
fn hash < S : hash:: Hasher > ( & self , into : & mut S ) {
571
592
self . inner . kind . hash ( into) ;
@@ -576,89 +597,90 @@ impl Hash for SourceId {
576
597
}
577
598
}
578
599
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
579
607
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`
586
608
fn hash < S : hash:: Hasher > ( & self , into : & mut S ) {
587
609
self . kind . hash ( into) ;
588
610
self . precise . hash ( into) ;
589
611
self . canonical_url . hash ( into) ;
590
612
}
591
613
}
592
614
615
+ /// This implementation must be synced with [`SourceIdInner::hash`].
593
616
impl PartialEq for SourceIdInner {
594
- /// This implementation must be synced with [`SourceIdInner::hash`].
595
617
fn eq ( & self , other : & Self ) -> bool {
596
618
self . kind == other. kind
597
619
&& self . precise == other. precise
598
620
&& self . canonical_url == other. canonical_url
599
621
}
600
622
}
601
623
602
- // forward to `Ord`
624
+ /// Forwards to `Ord`
603
625
impl PartialOrd for SourceKind {
604
626
fn partial_cmp ( & self , other : & SourceKind ) -> Option < Ordering > {
605
627
Some ( self . cmp ( other) )
606
628
}
607
629
}
608
630
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.
662
684
impl Ord for SourceKind {
663
685
fn cmp ( & self , other : & SourceKind ) -> Ordering {
664
686
match ( self , other) {
0 commit comments