@@ -257,24 +257,24 @@ func (p *importer) obj(tag int) {
257
257
case constTag :
258
258
pos := p .pos ()
259
259
pkg , name := p .qualifiedName ()
260
- typ := p .typ (nil )
260
+ typ := p .typ (nil , nil )
261
261
val := p .value ()
262
262
p .declare (types .NewConst (pos , pkg , name , typ , val ))
263
263
264
264
case aliasTag :
265
265
// TODO(gri) verify type alias hookup is correct
266
266
pos := p .pos ()
267
267
pkg , name := p .qualifiedName ()
268
- typ := p .typ (nil )
268
+ typ := p .typ (nil , nil )
269
269
p .declare (types .NewTypeName (pos , pkg , name , typ ))
270
270
271
271
case typeTag :
272
- p .typ (nil )
272
+ p .typ (nil , nil )
273
273
274
274
case varTag :
275
275
pos := p .pos ()
276
276
pkg , name := p .qualifiedName ()
277
- typ := p .typ (nil )
277
+ typ := p .typ (nil , nil )
278
278
p .declare (types .NewVar (pos , pkg , name , typ ))
279
279
280
280
case funcTag :
@@ -379,7 +379,11 @@ func (t *dddSlice) String() string { return "..." + t.elem.String() }
379
379
// the package currently imported. The parent package is needed for
380
380
// exported struct fields and interface methods which don't contain
381
381
// explicit package information in the export data.
382
- func (p * importer ) typ (parent * types.Package ) types.Type {
382
+ //
383
+ // A non-nil tname is used as the "owner" of the result type; i.e.,
384
+ // the result type is the underlying type of tname. tname is used
385
+ // to give interface methods a named receiver type where possible.
386
+ func (p * importer ) typ (parent * types.Package , tname * types.Named ) types.Type {
383
387
// if the type was seen before, i is its index (>= 0)
384
388
i := p .tagOrIndex ()
385
389
if i >= 0 {
@@ -409,15 +413,15 @@ func (p *importer) typ(parent *types.Package) types.Type {
409
413
t0 := types .NewNamed (obj .(* types.TypeName ), nil , nil )
410
414
411
415
// but record the existing type, if any
412
- t := obj .Type ().(* types.Named )
413
- p .record (t )
416
+ tname := obj .Type ().(* types.Named ) // tname is either t0 or the existing type
417
+ p .record (tname )
414
418
415
419
// read underlying type
416
- t0 .SetUnderlying (p .typ (parent ))
420
+ t0 .SetUnderlying (p .typ (parent , t0 ))
417
421
418
422
// interfaces don't have associated methods
419
423
if types .IsInterface (t0 ) {
420
- return t
424
+ return tname
421
425
}
422
426
423
427
// read associated methods
@@ -438,7 +442,7 @@ func (p *importer) typ(parent *types.Package) types.Type {
438
442
t0 .AddMethod (types .NewFunc (pos , parent , name , sig ))
439
443
}
440
444
441
- return t
445
+ return tname
442
446
443
447
case arrayTag :
444
448
t := new (types.Array )
@@ -447,7 +451,7 @@ func (p *importer) typ(parent *types.Package) types.Type {
447
451
}
448
452
449
453
n := p .int64 ()
450
- * t = * types .NewArray (p .typ (parent ), n )
454
+ * t = * types .NewArray (p .typ (parent , nil ), n )
451
455
return t
452
456
453
457
case sliceTag :
@@ -456,7 +460,7 @@ func (p *importer) typ(parent *types.Package) types.Type {
456
460
p .record (t )
457
461
}
458
462
459
- * t = * types .NewSlice (p .typ (parent ))
463
+ * t = * types .NewSlice (p .typ (parent , nil ))
460
464
return t
461
465
462
466
case dddTag :
@@ -465,7 +469,7 @@ func (p *importer) typ(parent *types.Package) types.Type {
465
469
p .record (t )
466
470
}
467
471
468
- t .elem = p .typ (parent )
472
+ t .elem = p .typ (parent , nil )
469
473
return t
470
474
471
475
case structTag :
@@ -483,7 +487,7 @@ func (p *importer) typ(parent *types.Package) types.Type {
483
487
p .record (t )
484
488
}
485
489
486
- * t = * types .NewPointer (p .typ (parent ))
490
+ * t = * types .NewPointer (p .typ (parent , nil ))
487
491
return t
488
492
489
493
case signatureTag :
@@ -502,6 +506,8 @@ func (p *importer) typ(parent *types.Package) types.Type {
502
506
// cannot expect the interface type to appear in a cycle, as any
503
507
// such cycle must contain a named type which would have been
504
508
// first defined earlier.
509
+ // TODO(gri) Is this still true now that we have type aliases?
510
+ // See issue #23225.
505
511
n := len (p .typList )
506
512
if p .trackAllTypes {
507
513
p .record (nil )
@@ -510,10 +516,10 @@ func (p *importer) typ(parent *types.Package) types.Type {
510
516
var embeddeds []* types.Named
511
517
for n := p .int (); n > 0 ; n -- {
512
518
p .pos ()
513
- embeddeds = append (embeddeds , p .typ (parent ).(* types.Named ))
519
+ embeddeds = append (embeddeds , p .typ (parent , nil ).(* types.Named ))
514
520
}
515
521
516
- t := types .NewInterface (p .methodList (parent ), embeddeds )
522
+ t := types .NewInterface (p .methodList (parent , tname ), embeddeds )
517
523
p .interfaceList = append (p .interfaceList , t )
518
524
if p .trackAllTypes {
519
525
p .typList [n ] = t
@@ -526,8 +532,8 @@ func (p *importer) typ(parent *types.Package) types.Type {
526
532
p .record (t )
527
533
}
528
534
529
- key := p .typ (parent )
530
- val := p .typ (parent )
535
+ key := p .typ (parent , nil )
536
+ val := p .typ (parent , nil )
531
537
* t = * types .NewMap (key , val )
532
538
return t
533
539
@@ -549,7 +555,7 @@ func (p *importer) typ(parent *types.Package) types.Type {
549
555
default :
550
556
errorf ("unexpected channel dir %d" , d )
551
557
}
552
- val := p .typ (parent )
558
+ val := p .typ (parent , nil )
553
559
* t = * types .NewChan (dir , val )
554
560
return t
555
561
@@ -573,7 +579,7 @@ func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags [
573
579
func (p * importer ) field (parent * types.Package ) (* types.Var , string ) {
574
580
pos := p .pos ()
575
581
pkg , name , alias := p .fieldName (parent )
576
- typ := p .typ (parent )
582
+ typ := p .typ (parent , nil )
577
583
tag := p .string ()
578
584
579
585
anonymous := false
@@ -597,22 +603,30 @@ func (p *importer) field(parent *types.Package) (*types.Var, string) {
597
603
return types .NewField (pos , pkg , name , typ , anonymous ), tag
598
604
}
599
605
600
- func (p * importer ) methodList (parent * types.Package ) (methods []* types.Func ) {
606
+ func (p * importer ) methodList (parent * types.Package , baseType * types. Named ) (methods []* types.Func ) {
601
607
if n := p .int (); n > 0 {
602
608
methods = make ([]* types.Func , n )
603
609
for i := range methods {
604
- methods [i ] = p .method (parent )
610
+ methods [i ] = p .method (parent , baseType )
605
611
}
606
612
}
607
613
return
608
614
}
609
615
610
- func (p * importer ) method (parent * types.Package ) * types.Func {
616
+ func (p * importer ) method (parent * types.Package , baseType * types. Named ) * types.Func {
611
617
pos := p .pos ()
612
618
pkg , name , _ := p .fieldName (parent )
619
+ // If we don't have a baseType, use a nil receiver.
620
+ // A receiver using the actual interface type (which
621
+ // we don't know yet) will be filled in when we call
622
+ // types.Interface.Complete.
623
+ var recv * types.Var
624
+ if baseType != nil {
625
+ recv = types .NewVar (token .NoPos , parent , "" , baseType )
626
+ }
613
627
params , isddd := p .paramList ()
614
628
result , _ := p .paramList ()
615
- sig := types .NewSignature (nil , params , result , isddd )
629
+ sig := types .NewSignature (recv , params , result , isddd )
616
630
return types .NewFunc (pos , pkg , name , sig )
617
631
}
618
632
@@ -668,7 +682,7 @@ func (p *importer) paramList() (*types.Tuple, bool) {
668
682
}
669
683
670
684
func (p * importer ) param (named bool ) (* types.Var , bool ) {
671
- t := p .typ (nil )
685
+ t := p .typ (nil , nil )
672
686
td , isddd := t .(* dddSlice )
673
687
if isddd {
674
688
t = types .NewSlice (td .elem )
0 commit comments