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

spec: method selectors do not auto-dereference #5769

Closed
griesemer opened this issue Jun 24, 2013 · 17 comments
Closed

spec: method selectors do not auto-dereference #5769

griesemer opened this issue Jun 24, 2013 · 17 comments
Labels
Documentation Issues describing a change to documentation. FrozenDueToAge
Milestone

Comments

@griesemer
Copy link
Contributor

http://play.golang.org/p/10YJgAZgUi

Both gc and gccgo complain about L12 in the above program, however, L13 is perfectly
valid.

As far as I can tell, nowhere in the spec does it say the L12 should be illegal.
Specifically, in http://tip.golang.org/ref/spec#Selectors it says: "Selectors
automatically dereference pointers to structs.".

The variable p is of type P which is a pointer to a struct. Thus, p.m should be the same
as (*p).m. It appears to be the case for p.x but not for p.m.

I believe this is a bug in the implementations.

For one, in order to get the same behavior as the compilers, a special case was needed
in go/types (I just submitted https://golang.org/cl/10459044 to match the
existing compilers). Furthermore, no code in the standard library  would break (not
compile anymore) if p.m where treated the same as p.x.

W/o looking at the specifics of an implementation, it is odd that only _after_ one knows
what one is looking for (a field or a method) does one know whether the automatic
indirection in the beginning should be done or not. That doesn't seem right.
@rsc
Copy link
Contributor

rsc commented Jun 24, 2013

Comment 1:

I believe that gc and gccgo are correct, and that if the spec disagrees we
should update the spec.
It's definitely a corner case, and I remember discussing it back in the
early days, but it's a corner case no matter what we do.
The issue is that when you say type P *S, P is defined to have no methods.
If p.m() did an auto-deref to get at the S.m method, then it would give the
incorrect impression that p of type P has an m method. That is, it would be
inconsistent with var x interface { m() } = p not compiling. It is true
that we have such inconsistencies due to the auto-& rule, but we've so far
avoided having them (at least in the implementation) due to the auto-* rule.
Since we already define the method set on a pointer to include the value
methods, I think the simplest spec fix would be to say that only field
selectors automatically dereference pointers to structs. If you have 'var
sp *S', then sp.m() is legal not because of ab selector deref but because
plain sp of type *S really does have an m method (as evidenced by var x
interface{ m() } = sp compiling).
Russ

@griesemer
Copy link
Contributor Author

Comment 2:

Labels changed: added documentation, removed compilerbug.

Owner changed to @griesemer.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 3:

Labels changed: added priority-later, go1.2, removed priority-triage.

@rsc
Copy link
Contributor

rsc commented Sep 11, 2013

Comment 4:

Labels changed: added go1.2maybe, removed go1.2.

@rsc
Copy link
Contributor

rsc commented Nov 25, 2013

Comment 5:

Labels changed: added go1.3, removed go1.2maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 6:

Labels changed: added release-go1.3.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 7:

Labels changed: removed go1.3.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 8:

Labels changed: added repo-main.

@rsc
Copy link
Contributor

rsc commented May 27, 2014

Comment 9:

Labels changed: added release-go1.4, removed release-go1.3.

@gopherbot
Copy link
Contributor

Comment 10:

CL https://golang.org/cl/132300043 mentions this issue.

@griesemer
Copy link
Contributor Author

Comment 11:

Issue #8713 has been merged into this issue.

@griesemer
Copy link
Contributor Author

Comment 12:

Issue #8713 has been merged into this issue.

@rsc
Copy link
Contributor

rsc commented Oct 28, 2014

Comment 13:

Labels changed: added release-go1.4maybe, removed release-go1.4.

@griesemer
Copy link
Contributor Author

Comment 14:

Here's a more complex case using embedded fields:
http://play.golang.org/p/c6VhjcIVdM

@gopherbot
Copy link
Contributor

Comment 15:

CL https://golang.org/cl/168790043 mentions this issue.

@rsc
Copy link
Contributor

rsc commented Nov 6, 2014

Comment 18:

Labels changed: added release-go1.5, removed release-go1.4maybe.

@griesemer
Copy link
Contributor Author

Comment 19:

This issue was closed by revision 40818cf.

Status changed to Fixed.

@griesemer griesemer added fixed Documentation Issues describing a change to documentation. labels Nov 11, 2014
@griesemer griesemer self-assigned this Nov 11, 2014
@bradfitz bradfitz modified the milestone: Go1.5 Dec 16, 2014
@golang golang locked and limited conversation to collaborators Jun 24, 2016
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jun 25, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Language clarification.

The existing rules for selector expressions imply
automatic dereferencing of pointers to struct fields.
They also implied automatic dereferencing of selectors
denoting methods. In almost all cases, such automatic
dereferencing does indeed take place for methods but the
reason is not the selector rules but the fact that method
sets include both methods with T and *T receivers; so for
a *T actual receiver, a method expecting a formal T
receiver, also accepts a *T (and the invocation or method
value expression is the reason for the auto-derefering).

However, the rules as stated so far implied that even in
case of a variable p of named pointer type P, a selector
expression p.f would always be shorthand for (*p).f. This
is true for field selectors f, but cannot be true for
method selectors since a named pointer type always has an
empty method set.

Named pointer types may never appear as anonymous field
types (and method receivers, for that matter), so this
only applies to variables declared of a named pointer
type. This is exceedingly rare and perhaps shouldn't be
permitted in the first place (but we cannot change that).

Amended the selector rules to make auto-deref of values
of named pointer types an exception to the general rules
and added corresponding examples with explanations.

Both gc and gccgo have a bug where they do auto-deref
pointers of named types in method selectors where they
should not:

See http://play.golang.org/p/c6VhjcIVdM , line 45.

Fixes golang#5769.
Fixes golang#8989.

LGTM=r, rsc
R=r, rsc, iant, ken
CC=golang-codereviews
https://golang.org/cl/168790043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jun 26, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Language clarification.

The existing rules for selector expressions imply
automatic dereferencing of pointers to struct fields.
They also implied automatic dereferencing of selectors
denoting methods. In almost all cases, such automatic
dereferencing does indeed take place for methods but the
reason is not the selector rules but the fact that method
sets include both methods with T and *T receivers; so for
a *T actual receiver, a method expecting a formal T
receiver, also accepts a *T (and the invocation or method
value expression is the reason for the auto-derefering).

However, the rules as stated so far implied that even in
case of a variable p of named pointer type P, a selector
expression p.f would always be shorthand for (*p).f. This
is true for field selectors f, but cannot be true for
method selectors since a named pointer type always has an
empty method set.

Named pointer types may never appear as anonymous field
types (and method receivers, for that matter), so this
only applies to variables declared of a named pointer
type. This is exceedingly rare and perhaps shouldn't be
permitted in the first place (but we cannot change that).

Amended the selector rules to make auto-deref of values
of named pointer types an exception to the general rules
and added corresponding examples with explanations.

Both gc and gccgo have a bug where they do auto-deref
pointers of named types in method selectors where they
should not:

See http://play.golang.org/p/c6VhjcIVdM , line 45.

Fixes golang#5769.
Fixes golang#8989.

LGTM=r, rsc
R=r, rsc, iant, ken
CC=golang-codereviews
https://golang.org/cl/168790043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jul 9, 2018
Language clarification.

The existing rules for selector expressions imply
automatic dereferencing of pointers to struct fields.
They also implied automatic dereferencing of selectors
denoting methods. In almost all cases, such automatic
dereferencing does indeed take place for methods but the
reason is not the selector rules but the fact that method
sets include both methods with T and *T receivers; so for
a *T actual receiver, a method expecting a formal T
receiver, also accepts a *T (and the invocation or method
value expression is the reason for the auto-derefering).

However, the rules as stated so far implied that even in
case of a variable p of named pointer type P, a selector
expression p.f would always be shorthand for (*p).f. This
is true for field selectors f, but cannot be true for
method selectors since a named pointer type always has an
empty method set.

Named pointer types may never appear as anonymous field
types (and method receivers, for that matter), so this
only applies to variables declared of a named pointer
type. This is exceedingly rare and perhaps shouldn't be
permitted in the first place (but we cannot change that).

Amended the selector rules to make auto-deref of values
of named pointer types an exception to the general rules
and added corresponding examples with explanations.

Both gc and gccgo have a bug where they do auto-deref
pointers of named types in method selectors where they
should not:

See http://play.golang.org/p/c6VhjcIVdM , line 45.

Fixes golang#5769.
Fixes golang#8989.

LGTM=r, rsc
R=r, rsc, iant, ken
CC=golang-codereviews
https://golang.org/cl/168790043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jul 20, 2018
Language clarification.

The existing rules for selector expressions imply
automatic dereferencing of pointers to struct fields.
They also implied automatic dereferencing of selectors
denoting methods. In almost all cases, such automatic
dereferencing does indeed take place for methods but the
reason is not the selector rules but the fact that method
sets include both methods with T and *T receivers; so for
a *T actual receiver, a method expecting a formal T
receiver, also accepts a *T (and the invocation or method
value expression is the reason for the auto-derefering).

However, the rules as stated so far implied that even in
case of a variable p of named pointer type P, a selector
expression p.f would always be shorthand for (*p).f. This
is true for field selectors f, but cannot be true for
method selectors since a named pointer type always has an
empty method set.

Named pointer types may never appear as anonymous field
types (and method receivers, for that matter), so this
only applies to variables declared of a named pointer
type. This is exceedingly rare and perhaps shouldn't be
permitted in the first place (but we cannot change that).

Amended the selector rules to make auto-deref of values
of named pointer types an exception to the general rules
and added corresponding examples with explanations.

Both gc and gccgo have a bug where they do auto-deref
pointers of named types in method selectors where they
should not:

See http://play.golang.org/p/c6VhjcIVdM , line 45.

Fixes golang#5769.
Fixes golang#8989.

LGTM=r, rsc
R=r, rsc, iant, ken
CC=golang-codereviews
https://golang.org/cl/168790043
wheatman pushed a commit to wheatman/go-akaros that referenced this issue Jul 30, 2018
Language clarification.

The existing rules for selector expressions imply
automatic dereferencing of pointers to struct fields.
They also implied automatic dereferencing of selectors
denoting methods. In almost all cases, such automatic
dereferencing does indeed take place for methods but the
reason is not the selector rules but the fact that method
sets include both methods with T and *T receivers; so for
a *T actual receiver, a method expecting a formal T
receiver, also accepts a *T (and the invocation or method
value expression is the reason for the auto-derefering).

However, the rules as stated so far implied that even in
case of a variable p of named pointer type P, a selector
expression p.f would always be shorthand for (*p).f. This
is true for field selectors f, but cannot be true for
method selectors since a named pointer type always has an
empty method set.

Named pointer types may never appear as anonymous field
types (and method receivers, for that matter), so this
only applies to variables declared of a named pointer
type. This is exceedingly rare and perhaps shouldn't be
permitted in the first place (but we cannot change that).

Amended the selector rules to make auto-deref of values
of named pointer types an exception to the general rules
and added corresponding examples with explanations.

Both gc and gccgo have a bug where they do auto-deref
pointers of named types in method selectors where they
should not:

See http://play.golang.org/p/c6VhjcIVdM , line 45.

Fixes golang#5769.
Fixes golang#8989.

LGTM=r, rsc
R=r, rsc, iant, ken
CC=golang-codereviews
https://golang.org/cl/168790043
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation Issues describing a change to documentation. FrozenDueToAge
Projects
None yet
Development

No branches or pull requests

4 participants