Skip to content

go/types: add Alias.Rhs method #66559

Closed
Closed

Description

@adonovan

Proposal Details

Background: Go 1.22's go/types defined new API for materialized alias types, as a step towards generic alias types. Alias has two operations: Underlying, which removes all Alias and Named constructors, recursively, returning the representation type; and Unalias, which removes only Alias constructors, again recursively, returning the first non-alias type. (A judicious sprinkling of Unalias operations throughout existing code is the minimal change to keep most existing go/types clients working.)

However, the API provides no way to remove a single Alias constructor. That means, for example, that there is no way for a client of go/types, given the types for:

type A = B
type B = int

to write a function that prints "type A = B" (without calling the existing ObjectString method). More importantly, import/export tools are unable to preserve the structure of the original types.

(Unalias is nonetheless useful, and Underlying is of course a requirement of the Type interface, but Alias types are not isomorphic to defined types in the way that, given type A B; type B int, the spec defines the underlying type of A as int, and otherwise stipulates no relationship between A and B.)

Proposal: We add an Alias.RHS accessor method, which removes exactly one Alias constructor. So, Alias.RHS(A) would return B.

@gri @findleyr @mdempsky

Activity

  1. added this to the Proposal milestone on Mar 27, 2024
  2. gopherbot commented on Mar 27, 2024

    @gopherbot
    Contributor

    Change https://go.dev/cl/574716 mentions this issue: go/types: ObjectString: remove only 1 Alias for "type A = RHS"

  3. moved this to Incoming in Proposalson Mar 27, 2024
  4. rsc commented on Mar 27, 2024

    @rsc
    Contributor

    Seems fine but we already spell it Rhs in other places, so we should do the same here.

  5. changed the title [-]proposal: go/types: add Alias.RHS accessor, which removes exactly one Alias constructor[/-] [+]proposal: go/types: add Alias.Rhs method[/+] on Mar 27, 2024
  6. rsc commented on Mar 27, 2024

    @rsc
    Contributor

    This proposal has been added to the active column of the proposals project
    and will now be reviewed at the weekly proposal review meetings.
    — rsc for the proposal review group

  7. moved this from Incoming to Active in Proposalson Mar 27, 2024
  8. adonovan commented on Mar 27, 2024

    @adonovan
    MemberAuthor

    Seems fine but we already spell it Rhs in other places, so we should do the same here.

    I'm not convinced: Rhs is not idiomatic spelling, and ast.AssignStmt.Rhs is essentially unrelated to types.Alias.RHS (you wouldn't plumb one through to the other, for example) so I don't see any downside to using the correct capitalization.

  9. ianlancetaylor commented on Mar 27, 2024

    @ianlancetaylor
    Contributor

    Note that go/types.Initializer also spells it Rhs.

    That is, it seems like we shouldn't use two different spellings in the same package.

  10. rsc commented on Mar 28, 2024

    @rsc
    Contributor

    The downside is that I am a gopher of very little brain, and I will never remember when to use Rhs and when to use RHS.
    The general rule is spell the same words the same way, so my brain can remember other things instead.

  11. findleyr commented on Mar 28, 2024

    @findleyr
    Contributor

    I'm not opposed, but I don't really follow the argument that Aliases are fundamentally different from Named types here. If we want to be able to print type A = B, why would we not also want to be able to print type A B? Isn't the question whether we preserve (and expose) the syntactic relationship in the type system?

    Historically, we've intentionally avoided preserving inessential syntax in types, with Interface embeddings being the one notable exception. In fact, I think this philosophy is why we didn't have an Alias type in the first place.

    Can we clarify our philosophical approach? Have we decided that it's generally a good idea to preserve the syntax of type definitions in the type system? If so, should we add Named.Rhs?

    Is this proposal also suggesting that we change the String value of an Alias? If so, we could of course do that without also exposing the Rhs accessor (though that would be inconsistent).

  12. adonovan commented on Mar 28, 2024

    @adonovan
    MemberAuthor

    OK, Rhs is is.

    I don't really follow the argument that Aliases are fundamentally different from Named types here.

    The main motive is that transiting export data should not make material changes to types, as this would cause tools like gopls to display different behavior depending on whether it obtained the types from a cache of export data or from type-annotated syntax. In the case of type A = B, the string representation shows the RHS type as declared; if the exporter were forced to use Unalias, then the reimported type would be type A = int, which would be confusing and even nondeterministic.

    By contrast, Named types do not reveal their middlemen in their API or their printed representation. (You raise an interesting question as to whether we would be better off if they did, but I don't think we need to address it now. IMHO the more troublesome difficulty with named types is not being able to distinguish A.f from B.f in type A B; type B struct{f int}, but we can't fix that.)

    Is this proposal also suggesting that we change the String value of an Alias?

    No.

  13. findleyr commented on Mar 28, 2024

    @findleyr
    Contributor

    Got it. So the problem is that there is an observable behavior of Aliases (their current type string) that can't be preserved through import. I agree that this needs to be fixed. I also agree that the behavior of showing the RHS in the type string is correct.

    We can worry about philosophy with respect to Named types later.

  14. 8 remaining items

  15. modified the milestones: Proposal, Backlog on Apr 24, 2024
  16. self-assigned this
    on Apr 24, 2024
  17. gopherbot commented on Apr 24, 2024

    @gopherbot
    Contributor

    Change https://go.dev/cl/581615 mentions this issue: go/types: add Alias.Rhs

  18. gopherbot commented on Apr 24, 2024

    @gopherbot
    Contributor

    Change https://go.dev/cl/581635 mentions this issue: internal/gcimporter: use Alias.Rhs, not unsafe hack

  19. added a commit that references this issue on Apr 24, 2024
    9b9de26
  20. modified the milestones: Backlog, Go1.23 on May 9, 2024
  21. locked and limited conversation to collaborators on May 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions