Repository: go
Issue: spec: wrong thing taken as a reference for method value rules
Labels: Documentation

### What is the URL of the page with the issue?

https://go.dev/ref/spec#Method_values

### What is your user agent?

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36

### Screenshot

![image](https://github.com/user-attachments/assets/cef4e064-eda2-4c96-b420-e25c7dd226c2)


### What did you do?

I have read the specification and I think the part related to the behavior (evaluation) of method values is not well written. I tried to write an issue quite thoroughly and step-by-step, while extensively quoting the specification and providing examples. For this reason, there is a bit more text. I didn't want the issue to be misinterpreted or for there to be any confusion about what I'm alluding to.

### What did you see happen?

Selector expression is in the spec explained as the way to select the field or the method with identifier `f` of the value `x`. 

> For a [primary expression](https://go.dev/ref/spec#Primary_expressions) x that is not a [package name](https://go.dev/ref/spec#Package_clause), the selector expression
> ```
> x.f
>```
> **denotes the field or method f** of the value x (or sometimes *x; see below). The identifier f is called the (field or method) selector; it must not be the [blank identifier](https://go.dev/ref/spec#Blank_identifier). The type of the selector expression is the type of f. If x is a package name, see the section on [qualified identifiers](https://go.dev/ref/spec#Qualified_identifiers).

According to spec, selection is done by traversing the types of the value `x` and its embedded fields and looking for the method or field with identifier `f`.

> **A selector f may denote a field or method f** of a type T, or it may refer to a field or method f of a nested [embedded field](https://go.dev/ref/spec#Struct_types) of T. The number of embedded fields traversed to reach f is called its depth in T. The depth of a field or method f declared in T is zero. The depth of a field or method f declared in an embedded field A in T is the depth of f in A plus one.

Next, the spec specifies some rules for selectors. The most important for what I'm talking about is the first:

> For a value x of type T or *T where T is not a pointer or interface type, **x.f denotes the field or method** at the shallowest depth in T where there is such an f. If there is not exactly [one f](https://go.dev/ref/spec#Uniqueness_of_identifiers) with shallowest depth, the selector expression is illegal.

Thus, it only talks about selecting ("taking") some concrete method or field `f`. Nothing else than that. Selectors just denote method or field (as bolded in all three cites). Any other logic related to the process of evaluation, creating method sets, implicit dereferencing of `x`, implicit taking address of `x` etc. is, according to the spec, out of scope for the selectors.

Consider the following example:
```
type T0 struct {
	x int
}

func (*T0) M0() {}

type T1 struct {
	x int
	T0
}

func (T1) M1()  {}
func (*T1) M2() {}
```
Following are all valid selectors for `x1` of type `T1` and `x2` of type `*T1` (I am talking here only about valid selectors according to the previously cited rule for them):
```
x1.M0
x2.M0
x1.M1
x1.M2
x2.M1
x2.M2
x1.x // from T1
x2.x // from T1
```

Further rules are then applied based on the "context" of the selected (obtained with the selector). Thus:
1. if we select field `x` with either `x1.x` or `x2.x`, then the rules related to the evaluation of the expression denoting identifier of the [variable](https://go.dev/ref/spec#Variables) is considered (since fields of the struct are considered as variables according to spec)
   > Structured variables of [array](https://go.dev/ref/spec#Array_types), [slice](https://go.dev/ref/spec#Slice_types), and [struct](https://go.dev/ref/spec#Struct_types) types have elements and fields that may be [addressed](https://go.dev/ref/spec#Address_operators) individually. **Each such element acts like a variable.**
2. if we select method with `x1.M1` and call it `x1.M1()`, then the rules related to [calls](https://go.dev/ref/spec#Calls) are applied:
    > A method call x.m() is valid if the [method set](https://go.dev/ref/spec#Method_sets) of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is [addressable](https://go.dev/ref/spec#Address_operators) and &x's method set contains m, x.m() is shorthand for (&x).m()
    - these rules include implicit dereferencing if the method is in the method set, so `x2.M1()` is shorthand for `(*x2).M1()` and implicit address taking if the receiver is addressable, so `x1.M2()` is shorthand for `(&x1).M2()`)
3. based on selectors, promotions and [method sets](https://go.dev/ref/spec#Method_sets) are defined
4. if we select method with `x1.M1`, then we selected method value and the rules related to the evaluation of the [method value](https://go.dev/ref/spec#Method_sets) are applied
5. and so on...

So, selector just selects/denotes field or method and then the corresponding rules are applied based on further context. For example:
```
type T1 struct{}

func (T1) M1()  {}
func (*T1) M2() {}

func R() T1 { return T1{} }

func main() {
	R().M1()
	R().M2() // error
}
```

In this example, both selector expressions `R().M1` and `R().M2` are valid according to the rule for selectors. Further rules apply because of [method call](https://go.dev/ref/spec#Calls) and then `R().M2()` fails to compile since return value of the function is not addressable (implicit `&R()` is not possible; rule 2).

Now, what I found to be incorrect in the specification.

It states the following for the [method values](https://go.dev/ref/spec#Method_values):

> As with [selectors](https://go.dev/ref/spec#Selectors), a reference to a non-interface method with a value receiver using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv.
> 
> As with [method calls](https://go.dev/ref/spec#Calls), a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp.

I agree with the second paragraph, but the first one seems incorrect to me. Selector just selects/denotes some method and then dereference is done "as part of other rules" (for example, if it is method call or method value).

Nowhere in the [selectors](https://go.dev/ref/spec#Selectors) section does it state that `pt.Mv is equivalent to (*pt).Mv`, or looking at the first example, that `x2.M1() is equivalent to (*x2).M1()` and that this implicit dereferencing is done. **It only states that `pt.Mv` (`x2.M1`) denotes a method, and that's it.** Moreover, if we follow this logic of implicitness, then for the second rule we could also reference selectors (instead of calls) as `t.Mp being equivalent to (&t).Mp`, or looking at the first example, `x1.M2() being equivalent to (&x1).M2()`. Here, the address is implicitly taken (just as in the first case where we have implicitly dereferencing). 

Whether selectors automatically dereference (or take address) is not stated anywhere (and I think it shouldn't be since they just denote method or field), so selectors can't be used as reference here. Both cases are correct by the rules for the selectors!

### What did you expect to see?

At the end:

> For a [primary expression](https://go.dev/ref/spec#Primary_expressions) x that is not a [package name](https://go.dev/ref/spec#Package_clause), the selector expression
> ```
> x.f
> ```
> **denotes the field or method f** of the value x (or sometimes *x; see below).

> A selector f may **denote a field or method f** of a type T, or it may refer to a field or method f of a nested [embedded field](https://go.dev/ref/spec#Struct_types) of T.

Selectors just select/denote field or method, and what will further happen is part of other rules.

In my opinion, issue could be solved by making the first paragraph also reference "calls" rather than selectors.

Additionally, since selector expression `x.f` where `f` is a field and `x` is a pointer type implicitly dereferences `x` first, it should be noted in [selector section](https://go.dev/ref/spec#Selectors). For example, something as this: 
- if the selector expression `x.f` denotes/selects field `f` and `x` is of pointer type, dereferencing is automatically done first, and then the selected field is treated as the [variable](https://go.dev/ref/spec#Variables); if the selector expression `x.f` denotes/selects method `f`, see the [method value](https://go.dev/ref/spec#Method_values).