@@ -191,25 +191,11 @@ fn get_source_id(
191
191
gctx : & GlobalContext ,
192
192
reg_or_index : Option < & RegistryOrIndex > ,
193
193
) -> CargoResult < RegistrySourceIds > {
194
- let sid = match reg_or_index {
195
- None => SourceId :: crates_io ( gctx) ?,
196
- Some ( RegistryOrIndex :: Index ( url) ) => SourceId :: for_registry ( url) ?,
197
- Some ( RegistryOrIndex :: Registry ( r) ) => SourceId :: alt_registry ( gctx, r) ?,
198
- } ;
199
- // Load source replacements that are built-in to Cargo.
200
- let builtin_replacement_sid = SourceConfigMap :: empty ( gctx) ?
201
- . load ( sid, & HashSet :: new ( ) ) ?
202
- . replaced_source_id ( ) ;
203
- let replacement_sid = SourceConfigMap :: new ( gctx) ?
204
- . load ( sid, & HashSet :: new ( ) ) ?
205
- . replaced_source_id ( ) ;
194
+ let sid = get_initial_source_id ( gctx, reg_or_index) ?;
195
+ let ( builtin_replacement_sid, replacement_sid) = get_replacement_source_ids ( gctx, sid) ?;
196
+
206
197
if reg_or_index. is_none ( ) && replacement_sid != builtin_replacement_sid {
207
- // Neither --registry nor --index was passed and the user has configured source-replacement.
208
- if let Some ( replacement_name) = replacement_sid. alt_registry_key ( ) {
209
- bail ! ( "crates-io is replaced with remote registry {replacement_name};\n include `--registry {replacement_name}` or `--registry crates-io`" ) ;
210
- } else {
211
- bail ! ( "crates-io is replaced with non-remote-registry source {replacement_sid};\n include `--registry crates-io` to use crates.io" ) ;
212
- }
198
+ bail ! ( gen_replacement_error( replacement_sid) ) ;
213
199
} else {
214
200
Ok ( RegistrySourceIds {
215
201
original : sid,
@@ -218,6 +204,7 @@ fn get_source_id(
218
204
}
219
205
}
220
206
207
+ // Very similar to get_source_id, but this function is used when the package_id is known.
221
208
fn get_source_id_with_package_id (
222
209
gctx : & GlobalContext ,
223
210
package_id : Option < PackageId > ,
@@ -229,42 +216,24 @@ fn get_source_id_with_package_id(
229
216
( Some ( RegistryOrIndex :: Index ( url) ) , None ) => ( false , SourceId :: for_registry ( url) ?) ,
230
217
( Some ( RegistryOrIndex :: Registry ( r) ) , None ) => ( false , SourceId :: alt_registry ( gctx, r) ?) ,
231
218
( Some ( reg_or_index) , Some ( package_id) ) => {
232
- let sid = match reg_or_index {
233
- RegistryOrIndex :: Index ( url) => SourceId :: for_registry ( url) ?,
234
- RegistryOrIndex :: Registry ( r) => SourceId :: alt_registry ( gctx, r) ?,
235
- } ;
219
+ let sid = get_initial_source_id_from_registry_or_index ( gctx, reg_or_index) ?;
236
220
let package_source_id = package_id. source_id ( ) ;
237
- // Same registry, use the package's source.
238
- if sid == package_source_id {
239
- ( true , sid)
221
+ // 1. Same registry, use the package's source.
222
+ // 2. Use the package's source if the specified registry is a replacement for the package's source.
223
+ if sid == package_source_id
224
+ || is_replacement_for_package_source ( gctx, sid, package_source_id) ?
225
+ {
226
+ ( true , package_source_id)
240
227
} else {
241
- let pkg_source_replacement_sid = SourceConfigMap :: new ( gctx) ?
242
- . load ( package_source_id, & HashSet :: new ( ) ) ?
243
- . replaced_source_id ( ) ;
244
- // Use the package's source if the specified registry is a replacement for the package's source.
245
- if pkg_source_replacement_sid == sid {
246
- ( true , package_source_id)
247
- } else {
248
- ( false , sid)
249
- }
228
+ ( false , sid)
250
229
}
251
230
}
252
231
} ;
253
- // Load source replacements that are built-in to Cargo.
254
- let builtin_replacement_sid = SourceConfigMap :: empty ( gctx) ?
255
- . load ( sid, & HashSet :: new ( ) ) ?
256
- . replaced_source_id ( ) ;
257
- let replacement_sid = SourceConfigMap :: new ( gctx) ?
258
- . load ( sid, & HashSet :: new ( ) ) ?
259
- . replaced_source_id ( ) ;
260
- // Check if the user has configured source-replacement for the registry we are querying.
232
+
233
+ let ( builtin_replacement_sid, replacement_sid) = get_replacement_source_ids ( gctx, sid) ?;
234
+
261
235
if reg_or_index. is_none ( ) && replacement_sid != builtin_replacement_sid {
262
- // Neither --registry nor --index was passed and the user has configured source-replacement.
263
- if let Some ( replacement_name) = replacement_sid. alt_registry_key ( ) {
264
- bail ! ( "crates-io is replaced with remote registry {replacement_name};\n include `--registry {replacement_name}` or `--registry crates-io`" ) ;
265
- } else {
266
- bail ! ( "crates-io is replaced with non-remote-registry source {replacement_sid};\n include `--registry crates-io` to use crates.io" ) ;
267
- }
236
+ bail ! ( gen_replacement_error( replacement_sid) ) ;
268
237
} else {
269
238
Ok ( (
270
239
use_package_source_id,
@@ -276,6 +245,67 @@ fn get_source_id_with_package_id(
276
245
}
277
246
}
278
247
248
+ fn get_initial_source_id (
249
+ gctx : & GlobalContext ,
250
+ reg_or_index : Option < & RegistryOrIndex > ,
251
+ ) -> CargoResult < SourceId > {
252
+ match reg_or_index {
253
+ None => SourceId :: crates_io ( gctx) ,
254
+ Some ( reg_or_index) => get_initial_source_id_from_registry_or_index ( gctx, reg_or_index) ,
255
+ }
256
+ }
257
+
258
+ fn get_initial_source_id_from_registry_or_index (
259
+ gctx : & GlobalContext ,
260
+ reg_or_index : & RegistryOrIndex ,
261
+ ) -> CargoResult < SourceId > {
262
+ match reg_or_index {
263
+ RegistryOrIndex :: Index ( url) => SourceId :: for_registry ( url) ,
264
+ RegistryOrIndex :: Registry ( r) => SourceId :: alt_registry ( gctx, r) ,
265
+ }
266
+ }
267
+
268
+ fn get_replacement_source_ids (
269
+ gctx : & GlobalContext ,
270
+ sid : SourceId ,
271
+ ) -> CargoResult < ( SourceId , SourceId ) > {
272
+ let builtin_replacement_sid = SourceConfigMap :: empty ( gctx) ?
273
+ . load ( sid, & HashSet :: new ( ) ) ?
274
+ . replaced_source_id ( ) ;
275
+ let replacement_sid = SourceConfigMap :: new ( gctx) ?
276
+ . load ( sid, & HashSet :: new ( ) ) ?
277
+ . replaced_source_id ( ) ;
278
+ Ok ( ( builtin_replacement_sid, replacement_sid) )
279
+ }
280
+
281
+ fn gen_replacement_error ( replacement_sid : SourceId ) -> String {
282
+ // Neither --registry nor --index was passed and the user has configured source-replacement.
283
+ let error_message = if let Some ( replacement_name) = replacement_sid. alt_registry_key ( ) {
284
+ format ! (
285
+ "crates-io is replaced with remote registry {};\n include `--registry {}` or `--registry crates-io`" ,
286
+ replacement_name, replacement_name
287
+ )
288
+ } else {
289
+ format ! (
290
+ "crates-io is replaced with non-remote-registry source {};\n include `--registry crates-io` to use crates.io" ,
291
+ replacement_sid
292
+ )
293
+ } ;
294
+
295
+ error_message
296
+ }
297
+
298
+ fn is_replacement_for_package_source (
299
+ gctx : & GlobalContext ,
300
+ sid : SourceId ,
301
+ package_source_id : SourceId ,
302
+ ) -> CargoResult < bool > {
303
+ let pkg_source_replacement_sid = SourceConfigMap :: new ( gctx) ?
304
+ . load ( package_source_id, & HashSet :: new ( ) ) ?
305
+ . replaced_source_id ( ) ;
306
+ Ok ( pkg_source_replacement_sid == sid)
307
+ }
308
+
279
309
struct RegistrySourceIds {
280
310
/// Use when looking up the auth token, or writing out `Cargo.lock`
281
311
original : SourceId ,
0 commit comments