Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: go/types: add Select function #70737

Open
adonovan opened this issue Dec 9, 2024 · 5 comments
Open

proposal: go/types: add Select function #70737

adonovan opened this issue Dec 9, 2024 · 5 comments
Labels
Milestone

Comments

@adonovan
Copy link
Member

adonovan commented Dec 9, 2024

Background: The type checker has two different APIs for the same concept, namely information about a selection of a field or method:

  • Info.Selections and MethodSet both use the record type Selection;
  • LookupFieldOrMethod returns a triple, (obj, indices, indirect).

There is no way to construct a Selection from the result of LookupFieldOrMethod. Especially when operating in parallel on the method sets of two types, it is a perennial nuisance that these corresponding items have different forms.

Proposal: We propose a function, Select, to bridge this gap.

package types

// Select selects the field or method whose ID is Id(pkg, name), on a value of type recv.
// See LookupFieldOrMethod for more detail.
func Select(recv Type, addressable bool, pkg *Package, name string) (Selection, bool) {
	obj, index, indirect := LookupFieldOrMethod(recv, addressable, pkg, name string)
	var kind SelectionKind 
	switch obj {
	case *types.Func:
		kind = MethodVal
	case *types.Var:
		kind = FieldVal
	}
	return Selection{kind, recv, obj, index, indirect}, obj != nil
}

Related:

@findleyr @griesemer @timothy-king

@gopherbot gopherbot added this to the Proposal milestone Dec 9, 2024
@gabyhelp
Copy link

gabyhelp commented Dec 9, 2024

Related Issues

Related Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

@adonovan adonovan moved this to Incoming in Proposals Dec 9, 2024
@griesemer
Copy link
Contributor

What is the problem with defining this (rather small) function external to go/types?

@adonovan
Copy link
Member Author

adonovan commented Dec 9, 2024

The expression Selection{...} cannot be written outside the package.

@griesemer
Copy link
Contributor

Some questions:

  1. Should this just be a simple constructor instead, as in
func MakeSelection(kind SelectionKind, recvType, obj Object, index []int,	indirect bool) Selection

which would provide max. flexibility; or, if not
2) What about the SelectionKind of MethodExpr
and, if we stick with the proposal
3) Why return a bool instead of an zero Selection, or just look for the nil Object?

@adonovan
Copy link
Member Author

adonovan commented Dec 9, 2024

  1. That would be maximally flexible, but I've never once needed MakeSelection other than as part of the Select operation, and the Select operation seems tidier to me.

  2. I updated the doc comment for Select to make explicit that it is about selections on a value (x.f) not on a type (T.f), so only the *Value kinds are possible; MethodExpr isn't needed.

  3. The zero selection has Kind of FieldVal, since we forgot to reserve the zero value for InvalidSelection. Having to remember that FieldVal doesn't imply Obj() != nil seems error-prone. A boolean makes it obvious.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

4 participants