@@ -243,20 +243,24 @@ func (e *invalidImportError) Unwrap() error {
243
243
//
244
244
// If the package is not present in any module selected from the requirement
245
245
// graph, importFromModules returns an *ImportMissingError.
246
- func importFromModules (ctx context.Context , path string , rs * Requirements , mg * ModuleGraph ) (m module.Version , dir string , err error ) {
246
+ //
247
+ // If the package is present in exactly one module, importFromModules will
248
+ // return the module, its root directory, and a list of other modules that
249
+ // lexically could have provided the package but did not.
250
+ func importFromModules (ctx context.Context , path string , rs * Requirements , mg * ModuleGraph ) (m module.Version , dir string , altMods []module.Version , err error ) {
247
251
if strings .Contains (path , "@" ) {
248
- return module.Version {}, "" , fmt .Errorf ("import path should not have @version" )
252
+ return module.Version {}, "" , nil , fmt .Errorf ("import path should not have @version" )
249
253
}
250
254
if build .IsLocalImport (path ) {
251
- return module.Version {}, "" , fmt .Errorf ("relative import not supported" )
255
+ return module.Version {}, "" , nil , fmt .Errorf ("relative import not supported" )
252
256
}
253
257
if path == "C" {
254
258
// There's no directory for import "C".
255
- return module.Version {}, "" , nil
259
+ return module.Version {}, "" , nil , nil
256
260
}
257
261
// Before any further lookup, check that the path is valid.
258
262
if err := module .CheckImportPath (path ); err != nil {
259
- return module.Version {}, "" , & invalidImportError {importPath : path , err : err }
263
+ return module.Version {}, "" , nil , & invalidImportError {importPath : path , err : err }
260
264
}
261
265
262
266
// Is the package in the standard library?
@@ -265,14 +269,14 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
265
269
for _ , mainModule := range MainModules .Versions () {
266
270
if MainModules .InGorootSrc (mainModule ) {
267
271
if dir , ok , err := dirInModule (path , MainModules .PathPrefix (mainModule ), MainModules .ModRoot (mainModule ), true ); err != nil {
268
- return module.Version {}, dir , err
272
+ return module.Version {}, dir , nil , err
269
273
} else if ok {
270
- return mainModule , dir , nil
274
+ return mainModule , dir , nil , nil
271
275
}
272
276
}
273
277
}
274
278
dir := filepath .Join (cfg .GOROOT , "src" , path )
275
- return module.Version {}, dir , nil
279
+ return module.Version {}, dir , nil , nil
276
280
}
277
281
278
282
// -mod=vendor is special.
@@ -283,19 +287,19 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
283
287
mainDir , mainOK , mainErr := dirInModule (path , MainModules .PathPrefix (mainModule ), modRoot , true )
284
288
vendorDir , vendorOK , _ := dirInModule (path , "" , filepath .Join (modRoot , "vendor" ), false )
285
289
if mainOK && vendorOK {
286
- return module.Version {}, "" , & AmbiguousImportError {importPath : path , Dirs : []string {mainDir , vendorDir }}
290
+ return module.Version {}, "" , nil , & AmbiguousImportError {importPath : path , Dirs : []string {mainDir , vendorDir }}
287
291
}
288
292
// Prefer to return main directory if there is one,
289
293
// Note that we're not checking that the package exists.
290
294
// We'll leave that for load.
291
295
if ! vendorOK && mainDir != "" {
292
- return mainModule , mainDir , nil
296
+ return mainModule , mainDir , nil , nil
293
297
}
294
298
if mainErr != nil {
295
- return module.Version {}, "" , mainErr
299
+ return module.Version {}, "" , nil , mainErr
296
300
}
297
301
readVendorList (mainModule )
298
- return vendorPkgModule [path ], vendorDir , nil
302
+ return vendorPkgModule [path ], vendorDir , nil , nil
299
303
}
300
304
301
305
// Check each module on the build list.
@@ -316,7 +320,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
316
320
// already non-nil, then we attempt to load the package using the full
317
321
// requirements in mg.
318
322
for {
319
- var sumErrMods []module.Version
323
+ var sumErrMods , altMods []module.Version
320
324
for prefix := path ; prefix != "." ; prefix = pathpkg .Dir (prefix ) {
321
325
var (
322
326
v string
@@ -350,13 +354,15 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
350
354
// continue the loop and find the package in some other module,
351
355
// we need to look at this module to make sure the import is
352
356
// not ambiguous.
353
- return module.Version {}, "" , err
357
+ return module.Version {}, "" , nil , err
354
358
}
355
359
if dir , ok , err := dirInModule (path , m .Path , root , isLocal ); err != nil {
356
- return module.Version {}, "" , err
360
+ return module.Version {}, "" , nil , err
357
361
} else if ok {
358
362
mods = append (mods , m )
359
363
dirs = append (dirs , dir )
364
+ } else {
365
+ altMods = append (altMods , m )
360
366
}
361
367
}
362
368
@@ -369,23 +375,23 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
369
375
mods [i ], mods [j ] = mods [j ], mods [i ]
370
376
dirs [i ], dirs [j ] = dirs [j ], dirs [i ]
371
377
}
372
- return module.Version {}, "" , & AmbiguousImportError {importPath : path , Dirs : dirs , Modules : mods }
378
+ return module.Version {}, "" , nil , & AmbiguousImportError {importPath : path , Dirs : dirs , Modules : mods }
373
379
}
374
380
375
381
if len (sumErrMods ) > 0 {
376
382
for i := 0 ; i < len (sumErrMods )/ 2 ; i ++ {
377
383
j := len (sumErrMods ) - 1 - i
378
384
sumErrMods [i ], sumErrMods [j ] = sumErrMods [j ], sumErrMods [i ]
379
385
}
380
- return module.Version {}, "" , & ImportMissingSumError {
386
+ return module.Version {}, "" , nil , & ImportMissingSumError {
381
387
importPath : path ,
382
388
mods : sumErrMods ,
383
389
found : len (mods ) > 0 ,
384
390
}
385
391
}
386
392
387
393
if len (mods ) == 1 {
388
- return mods [0 ], dirs [0 ], nil
394
+ return mods [0 ], dirs [0 ], altMods , nil
389
395
}
390
396
391
397
if mg != nil {
@@ -395,7 +401,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
395
401
if ! HasModRoot () {
396
402
queryErr = ErrNoModRoot
397
403
}
398
- return module.Version {}, "" , & ImportMissingError {Path : path , QueryErr : queryErr , isStd : pathIsStd }
404
+ return module.Version {}, "" , nil , & ImportMissingError {Path : path , QueryErr : queryErr , isStd : pathIsStd }
399
405
}
400
406
401
407
// So far we've checked the root dependencies.
@@ -406,7 +412,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
406
412
// the module graph, so we can't return an ImportMissingError here — one
407
413
// of the missing modules might actually contain the package in question,
408
414
// in which case we shouldn't go looking for it in some new dependency.
409
- return module.Version {}, "" , err
415
+ return module.Version {}, "" , nil , err
410
416
}
411
417
}
412
418
}
0 commit comments