@@ -1394,28 +1394,38 @@ func (g *graph) stmt(stmt ast.Stmt, by types.Object) {
13941394// embeddedField sees the field declared by the embedded field node, and marks the type as used by the field.
13951395//
13961396// Embedded fields are special in two ways: they don't have names, so we don't have immediate access to an ast.Ident to
1397- // resolve to the field's types.Var, and we cannot use g.read on the type because eventually we do get to an ast.Ident,
1398- // and ObjectOf resolves embedded fields to the field they declare, not the type. That's why we have code specially for
1399- // handling embedded fields.
1397+ // resolve to the field's types.Var and need to instead walk the AST , and we cannot use g.read on the type because
1398+ // eventually we do get to an ast.Ident, and ObjectOf resolves embedded fields to the field they declare, not the type.
1399+ // That's why we have code specially for handling embedded fields.
14001400func (g * graph ) embeddedField (node ast.Node , by types.Object ) * types.Var {
14011401 // We need to traverse the tree to find the ast.Ident, but all the nodes we traverse should be used by the object we
14021402 // get once we resolve the ident. Collect the nodes and process them once we've found the ident.
14031403 nodes := make ([]ast.Node , 0 , 4 )
14041404 for {
14051405 switch node_ := node .(type ) {
14061406 case * ast.Ident :
1407+ // obj is the field
14071408 obj := g .info .ObjectOf (node_ ).(* types.Var )
1409+ // the field is declared by the enclosing type
14081410 g .see (obj , by )
14091411 for _ , n := range nodes {
14101412 g .read (n , obj )
14111413 }
1412- switch typ := typeutil .Dereference (g .info .TypeOf (node_ )).(type ) {
1413- case * types.Named :
1414- g .use (typ .Obj (), obj )
1415- case * types.Basic :
1416- // Nothing to do
1417- default :
1418- lint .ExhaustiveTypeSwitch (typ )
1414+
1415+ if tname , ok := g .info .Uses [node_ ].(* types.TypeName ); ok && tname .IsAlias () {
1416+ // When embedding an alias we want to use the alias, not what the alias points to.
1417+ g .use (tname , obj )
1418+ } else {
1419+ switch typ := typeutil .Dereference (g .info .TypeOf (node_ )).(type ) {
1420+ case * types.Named :
1421+ // (7.2) fields use their types
1422+ g .use (typ .Obj (), obj )
1423+ case * types.Basic :
1424+ // Nothing to do
1425+ default :
1426+ // Other types are only possible for aliases, which we've already handled
1427+ lint .ExhaustiveTypeSwitch (typ )
1428+ }
14191429 }
14201430 return obj
14211431 case * ast.StarExpr :
@@ -1518,6 +1528,9 @@ func (g *graph) namedType(typ *types.TypeName, spec ast.Expr) {
15181528 obj := g .info .ObjectOf (name )
15191529 g .see (obj , typ )
15201530 // (7.2) fields use their types
1531+ //
1532+ // This handles aliases correctly because ObjectOf(alias) returns the TypeName of the alias, not
1533+ // what the alias points to.
15211534 g .read (field .Type , obj )
15221535 if name .Name == "_" {
15231536 // (9.9) objects named the blank identifier are used
0 commit comments