@@ -189,11 +189,34 @@ enum MaybeIndexSummary {
189189/// from a line from a raw index file, or a JSON blob from on-disk index cache.
190190///
191191/// In addition to a full [`Summary`], we have information on whether it is `yanked`.
192- pub struct IndexSummary {
193- pub summary : Summary ,
194- pub yanked : bool ,
195- /// Schema version, see [`IndexPackage::v`].
196- v : u32 ,
192+ #[ derive( Clone , Debug ) ]
193+ pub enum IndexSummary {
194+ /// Available for consideration
195+ Candidate ( Summary ) ,
196+ /// Yanked within its registry
197+ Yanked ( Summary ) ,
198+ /// From a newer schema version and is likely incomplete or inaccurate
199+ Unsupported ( Summary , u32 ) ,
200+ }
201+
202+ impl IndexSummary {
203+ /// Extract the summary from any variant
204+ pub fn as_summary ( & self ) -> & Summary {
205+ match self {
206+ IndexSummary :: Candidate ( sum)
207+ | IndexSummary :: Yanked ( sum)
208+ | IndexSummary :: Unsupported ( sum, _) => sum,
209+ }
210+ }
211+
212+ /// Extract the package id from any variant
213+ pub fn package_id ( & self ) -> PackageId {
214+ match self {
215+ IndexSummary :: Candidate ( sum)
216+ | IndexSummary :: Yanked ( sum)
217+ | IndexSummary :: Unsupported ( sum, _) => sum. package_id ( ) ,
218+ }
219+ }
197220}
198221
199222/// A representation of the cache on disk that Cargo maintains of summaries.
@@ -387,11 +410,11 @@ impl<'cfg> RegistryIndex<'cfg> {
387410 let req = OptVersionReq :: exact ( pkg. version ( ) ) ;
388411 let summary = self . summaries ( & pkg. name ( ) , & req, load) ?;
389412 let summary = ready ! ( summary)
390- . filter ( |s| s. summary . version ( ) == pkg. version ( ) )
413+ . filter ( |s| s. package_id ( ) . version ( ) == pkg. version ( ) )
391414 . next ( ) ;
392415 Poll :: Ready ( Ok ( summary
393416 . ok_or_else ( || internal ( format ! ( "no hash listed for {}" , pkg) ) ) ?
394- . summary
417+ . as_summary ( )
395418 . checksum ( )
396419 . ok_or_else ( || internal ( format ! ( "no hash listed for {}" , pkg) ) ) ?) )
397420 }
@@ -435,26 +458,24 @@ impl<'cfg> RegistryIndex<'cfg> {
435458 . versions
436459 . iter_mut ( )
437460 . filter_map ( move |( k, v) | if req. matches ( k) { Some ( v) } else { None } )
438- . filter_map ( move |maybe| match maybe. parse ( raw_data, source_id) {
439- Ok ( summary) => Some ( summary) ,
440- Err ( e) => {
441- info ! ( "failed to parse `{}` registry package: {}" , name, e) ;
442- None
443- }
444- } )
445- . filter ( move |is| {
446- if is. v == 3 && bindeps {
447- true
448- } else if is. v > INDEX_V_MAX {
449- debug ! (
450- "unsupported schema version {} ({} {})" ,
451- is. v,
452- is. summary. name( ) ,
453- is. summary. version( )
454- ) ;
455- false
456- } else {
457- true
461+ . filter_map ( move |maybe| {
462+ match maybe. parse ( raw_data, source_id, bindeps) {
463+ Ok ( sum @ IndexSummary :: Candidate ( _) | sum @ IndexSummary :: Yanked ( _) ) => {
464+ Some ( sum)
465+ }
466+ Ok ( IndexSummary :: Unsupported ( summary, v) ) => {
467+ debug ! (
468+ "unsupported schema version {} ({} {})" ,
469+ v,
470+ summary. name( ) ,
471+ summary. version( )
472+ ) ;
473+ None
474+ }
475+ Err ( e) => {
476+ info ! ( "failed to parse `{}` registry package: {}" , name, e) ;
477+ None
478+ }
458479 }
459480 } ) ) )
460481 }
@@ -573,12 +594,14 @@ impl<'cfg> RegistryIndex<'cfg> {
573594 // does not satisfy the requirements, then resolution will
574595 // fail. Unfortunately, whether or not something is optional
575596 // is not known here.
576- . filter ( |s| ( online || load. is_crate_downloaded ( s. summary . package_id ( ) ) ) )
597+ . filter ( |s| ( online || load. is_crate_downloaded ( s. package_id ( ) ) ) )
577598 // Next filter out all yanked packages. Some yanked packages may
578599 // leak through if they're in a whitelist (aka if they were
579600 // previously in `Cargo.lock`
580- . filter ( |s| !s. yanked || yanked_whitelist. contains ( & s. summary . package_id ( ) ) )
581- . map ( |s| s. summary . clone ( ) ) ;
601+ . filter ( |s| {
602+ !matches ! ( s, IndexSummary :: Yanked ( _) ) || yanked_whitelist. contains ( & s. package_id ( ) )
603+ } )
604+ . map ( |s| s. clone ( ) ) ;
582605
583606 // Handle `cargo update --precise` here.
584607 let precise = source_id. precise_registry_version ( name) ;
@@ -589,7 +612,7 @@ impl<'cfg> RegistryIndex<'cfg> {
589612 // by build metadata. This shouldn't be allowed, but since
590613 // it is, this will honor it if requested. However, if not
591614 // specified, then ignore it.
592- let s_vers = s. version ( ) ;
615+ let s_vers = s. package_id ( ) . version ( ) ;
593616 match ( s_vers. build . is_empty ( ) , requested. build . is_empty ( ) ) {
594617 ( true , true ) => s_vers == requested,
595618 ( true , false ) => false ,
@@ -611,7 +634,7 @@ impl<'cfg> RegistryIndex<'cfg> {
611634
612635 let mut count = 0 ;
613636 for summary in summaries {
614- f ( summary) ;
637+ f ( summary. as_summary ( ) . clone ( ) ) ;
615638 count += 1 ;
616639 }
617640 Poll :: Ready ( Ok ( count) )
@@ -625,8 +648,8 @@ impl<'cfg> RegistryIndex<'cfg> {
625648 ) -> Poll < CargoResult < bool > > {
626649 let req = OptVersionReq :: exact ( pkg. version ( ) ) ;
627650 let found = ready ! ( self . summaries( & pkg. name( ) , & req, load) ) ?
628- . filter ( |s| s. summary . version ( ) == pkg. version ( ) )
629- . any ( |summary| summary. yanked ) ;
651+ . filter ( |s| s. package_id ( ) . version ( ) == pkg. version ( ) )
652+ . any ( |summary| matches ! ( summary, IndexSummary :: Yanked ( _ ) ) ) ;
630653 Poll :: Ready ( Ok ( found) )
631654 }
632655}
@@ -682,6 +705,8 @@ impl Summaries {
682705
683706 let response = ready ! ( load. load( root, relative, index_version. as_deref( ) ) ?) ;
684707
708+ let bindeps = config. cli_unstable ( ) . bindeps ;
709+
685710 match response {
686711 LoadResponse :: CacheValid => {
687712 tracing:: debug!( "fast path for registry cache of {:?}" , relative) ;
@@ -712,7 +737,7 @@ impl Summaries {
712737 // allow future cargo implementations to break the
713738 // interpretation of each line here and older cargo will simply
714739 // ignore the new lines.
715- let summary = match IndexSummary :: parse ( line, source_id) {
740+ let summary = match IndexSummary :: parse ( line, source_id, bindeps ) {
716741 Ok ( summary) => summary,
717742 Err ( e) => {
718743 // This should only happen when there is an index
@@ -731,7 +756,7 @@ impl Summaries {
731756 continue ;
732757 }
733758 } ;
734- let version = summary. summary . package_id ( ) . version ( ) . clone ( ) ;
759+ let version = summary. package_id ( ) . version ( ) . clone ( ) ;
735760 cache. versions . push ( ( version. clone ( ) , line) ) ;
736761 ret. versions . insert ( version, summary. into ( ) ) ;
737762 }
@@ -865,12 +890,17 @@ impl MaybeIndexSummary {
865890 /// Does nothing if this is already `Parsed`, and otherwise the `raw_data`
866891 /// passed in is sliced with the bounds in `Unparsed` and then actually
867892 /// parsed.
868- fn parse ( & mut self , raw_data : & [ u8 ] , source_id : SourceId ) -> CargoResult < & IndexSummary > {
893+ fn parse (
894+ & mut self ,
895+ raw_data : & [ u8 ] ,
896+ source_id : SourceId ,
897+ bindeps : bool ,
898+ ) -> CargoResult < & IndexSummary > {
869899 let ( start, end) = match self {
870900 MaybeIndexSummary :: Unparsed { start, end } => ( * start, * end) ,
871901 MaybeIndexSummary :: Parsed ( summary) => return Ok ( summary) ,
872902 } ;
873- let summary = IndexSummary :: parse ( & raw_data[ start..end] , source_id) ?;
903+ let summary = IndexSummary :: parse ( & raw_data[ start..end] , source_id, bindeps ) ?;
874904 * self = MaybeIndexSummary :: Parsed ( summary) ;
875905 match self {
876906 MaybeIndexSummary :: Unparsed { .. } => unreachable ! ( ) ,
@@ -891,7 +921,7 @@ impl IndexSummary {
891921 ///
892922 /// The `line` provided is expected to be valid JSON. It is supposed to be
893923 /// a [`IndexPackage`].
894- fn parse ( line : & [ u8 ] , source_id : SourceId ) -> CargoResult < IndexSummary > {
924+ fn parse ( line : & [ u8 ] , source_id : SourceId , bindeps : bool ) -> CargoResult < IndexSummary > {
895925 // ****CAUTION**** Please be extremely careful with returning errors
896926 // from this function. Entries that error are not included in the
897927 // index cache, and can cause cargo to get confused when switching
@@ -924,11 +954,20 @@ impl IndexSummary {
924954 }
925955 let mut summary = Summary :: new ( pkgid, deps, & features, links, rust_version) ?;
926956 summary. set_checksum ( cksum) ;
927- Ok ( IndexSummary {
928- summary,
929- yanked : yanked. unwrap_or ( false ) ,
930- v,
931- } )
957+
958+ let v_max = if bindeps {
959+ INDEX_V_MAX + 1
960+ } else {
961+ INDEX_V_MAX
962+ } ;
963+
964+ if v_max < v {
965+ return Ok ( IndexSummary :: Unsupported ( summary, v) ) ;
966+ }
967+ if yanked. unwrap_or ( false ) {
968+ return Ok ( IndexSummary :: Yanked ( summary) ) ;
969+ }
970+ Ok ( IndexSummary :: Candidate ( summary) )
932971 }
933972}
934973
0 commit comments