@@ -1513,17 +1513,96 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label {
15131513 return extractTypeWithFlags (tw , tp , false )
15141514}
15151515
1516+ func containsAliasTypes (tp types.Type ) bool {
1517+ switch tp := tp .(type ) {
1518+ case * types.Basic :
1519+ return false
1520+ case * types.Array :
1521+ return containsAliasTypes (tp .Elem ())
1522+ case * types.Slice :
1523+ return containsAliasTypes (tp .Elem ())
1524+ case * types.Struct :
1525+ for i := 0 ; i < tp .NumFields (); i ++ {
1526+ field := tp .Field (i )
1527+ if containsAliasTypes (field .Type ()) {
1528+ return true
1529+ }
1530+ }
1531+ return false
1532+ case * types.Pointer :
1533+ return containsAliasTypes (tp .Elem ())
1534+ case * types.Interface :
1535+ for i := 0 ; i < tp .NumMethods (); i ++ {
1536+ meth := tp .Method (i )
1537+ if containsAliasTypes (meth .Type ()) {
1538+ return true
1539+ }
1540+ }
1541+ for i := 0 ; i < tp .NumEmbeddeds (); i ++ {
1542+ if containsAliasTypes (tp .EmbeddedType (i )) {
1543+ return true
1544+ }
1545+ }
1546+ return false
1547+ case * types.Tuple :
1548+ for i := 0 ; i < tp .Len (); i ++ {
1549+ if containsAliasTypes (tp .At (i ).Type ()) {
1550+ return true
1551+ }
1552+ }
1553+ return false
1554+ case * types.Signature :
1555+ params , results := tp .Params (), tp .Results ()
1556+ if params != nil {
1557+ for i := 0 ; i < params .Len (); i ++ {
1558+ param := params .At (i )
1559+ if containsAliasTypes (param .Type ()) {
1560+ return true
1561+ }
1562+ }
1563+ }
1564+ if results != nil {
1565+ for i := 0 ; i < results .Len (); i ++ {
1566+ result := results .At (i )
1567+ if containsAliasTypes (result .Type ()) {
1568+ return true
1569+ }
1570+ }
1571+ }
1572+ return false
1573+ case * types.Map :
1574+ return containsAliasTypes (tp .Key ()) || containsAliasTypes (tp .Elem ())
1575+ case * types.Chan :
1576+ return containsAliasTypes (tp .Elem ())
1577+ case * types.Named :
1578+ return false
1579+ case * types.TypeParam :
1580+ return false
1581+ case * types.Union :
1582+ for i := 0 ; i < tp .Len (); i ++ {
1583+ term := tp .Term (i )
1584+ if containsAliasTypes (term .Type ()) {
1585+ return true
1586+ }
1587+ }
1588+ return false
1589+ case * types.Alias :
1590+ return true
1591+ default :
1592+ log .Fatalf ("unexpected type %T" , tp )
1593+ }
1594+ return false
1595+ }
1596+
15161597func extractTypeWithFlags (tw * trap.Writer , tp types.Type , transparentAliases bool ) trap.Label {
15171598 lbl , exists := getTypeLabelWithFlags (tw , tp , transparentAliases )
15181599 if ! exists {
1519- if ! transparentAliases {
1600+ if ! transparentAliases && containsAliasTypes ( tp ) {
15201601 // Ensure the (deep) underlying type is also extracted, so that it is
15211602 // possible to implement deepUnalias in QL.
15221603 // For example, if we had type A = int and type B = string, we would need
15231604 // to extract map[string]int so that deepUnalias(map[B]A) has a real member
15241605 // of @type to return.
1525- //
1526- // TODO: consider using a newtype to do this instead.
15271606 extractTypeWithFlags (tw , tp , true )
15281607 }
15291608 var kind int
@@ -1709,6 +1788,11 @@ func getTypeLabelWithFlags(tw *trap.Writer, tp types.Type, transparentAliases bo
17091788 typeLabelKey := trap.TypeLabelsKey {Type : tp , TransparentAliases : transparentAliases }
17101789 lbl , exists := tw .Labeler .TypeLabels [typeLabelKey ]
17111790 if ! exists {
1791+ if transparentAliases && ! containsAliasTypes (tp ) {
1792+ // No aliases involved, so the label is the same as the non-transparent version
1793+ // of the same type.
1794+ return getTypeLabelWithFlags (tw , tp , false )
1795+ }
17121796 switch tp := tp .(type ) {
17131797 case * types.Basic :
17141798 lbl = tw .Labeler .GlobalID (fmt .Sprintf ("%d;basictype" , tp .Kind ()))
0 commit comments