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: semantics of recursive interfaces are unspecified #8691

Closed
adonovan opened this issue Sep 10, 2014 · 2 comments
Closed

spec: semantics of recursive interfaces are unspecified #8691

adonovan opened this issue Sep 10, 2014 · 2 comments

Comments

@adonovan
Copy link

@adonovan adonovan commented Sep 10, 2014

I can't find any wording in the spec that would explain the legality or otherwise of
this program.  The question is whether isomorphic recursive interfaces are identical and
thus mutually assignable.   My intuition about interfaces would suggest that these types
ought to be identical.

http://play.golang.org/p/r92J5TY-WI

package main 

type I interface {
    f() I
}
type J interface {
    f() J
}

func main() {
    var i I
    var j J
    i = j
    j = i
}

gc and go/types both give an error.

gc:
prog.go:13: cannot use j (type J) as type I in assignment:
    J does not implement I (wrong type for f method)
        have f() J
        want f() I
prog.go:14: cannot use i (type I) as type J in assignment:
    I does not implement J (wrong type for f method)
        have f() I
        want f() J

go/types:
a.go:13:6: cannot assign j (variable of type J) to i (variable of type I)
@griesemer
Copy link
Contributor

@griesemer griesemer commented Sep 10, 2014

Comment 1:

This is consequence from the spec's assignability rules even it's perhaps not obvious. I
don't think it requires further clarification in the spec (it's too special a case, and
the compiler's error message explains the problem very well).
The interfaces are not assignable because they are different since the method signatures
are not identical: The result type of I.f is I, while the result type of J.f is J. I and
J are named types and they are different.
Or in other words, when comparing function types, type identify rules apply, not
assignment rules.
The following program compiles fine:
http://play.golang.org/p/fA5sHQXaFv
gc provides a clear error message explaining the problem. go/types can do this as well
(I think there's a TODO somewhere).
One might argue that for interface identity (involved here when comparing function
result types), perhaps different rules should apply. But until this situation becomes a
real problem, I think we should stick with the rules we have (I can understand that the
situation may occur, but it's probably a rare case).

Labels changed: added repo-main, documentation.

Status changed to WorkingAsIntended.

@adonovan
Copy link
Author

@adonovan adonovan commented Sep 10, 2014

Comment 2:

I see.  Thanks for clarifying.
This example makes things more obvious (to me):
http://play.golang.org/p/zwIhMcl5CC
@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants