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

cmd/compile: odd/inconsistent behavior with cyclic declarations #6590

Open
griesemer opened this issue Oct 15, 2013 · 4 comments

Comments

@griesemer
Copy link
Contributor

commented Oct 15, 2013

This applies to:

$ go version
go version go1.1.1 linux/amd64

The following program compiles w/o errors:

    package p

    import "unsafe"

    type A [unsafe.Sizeof(x)]T

    type T interface {
        m(A)
    }

    var x T

Adding one extra declaration leads to a cycle error:

    package p

    import "unsafe"

    const n = unsafe.Sizeof(x)  // <<< EXTRA DECLARATION

    type A [unsafe.Sizeof(x)]T

    type T interface {
        m(A)
    }

    var x T

$ go tool 6g x.go
x.go:7: typechecking loop involving x
    x.go:7 unsafe.Sizeof(x)
    x.go:7 []unsafe.Sizeof(x)
    x.go:7 A
    x.go:10 <T>
    x.go:9 T
    x.go:13 x
    x.go:5 unsafe.Sizeof(x)
    x.go:5 n
    x.go:5 <node DCLCONST>
x.go:7: invalid expression unsafe.Sizeof(x)

even though the n is not even used (and thus cannot be part of a cycle). What is more
surprising even is that when moving that same declaration to the bottom of the file:

    package p

    import "unsafe"

    type A [unsafe.Sizeof(x)]T

    type T interface {
        m(A)
    }

    var x T

    const n = unsafe.Sizeof(x)  // <<< EXTRA DECLARATION MOVED DOWN

the program again compiles w/o errors. But top-level declarations do not depend of
source order in Go, so this is clearly a bug somewhere.

Furthermore, using n now in the type of A:

    package p

    import "unsafe"

    type A [n]T  // <<< USING n HERE

    type T interface {
        m(A)
    }

    var x T

    const n = unsafe.Sizeof(x)

appears to work fine (and changing this to a main package and printing out n produces
the correct value 16). Moving the const declaration up again, leads to the cycle error,
however with a less detailed error now:

    package p

    import "unsafe"

    const n = unsafe.Sizeof(x)  // <<< MOVED DECL UP AGAIN

    type A [n]T

    type T interface {
        m(A)
    }

    var x T

$ go tool 6g x.go
x.go:5: constant definition loop
    x.go:5: n uses n
x.go:7: invalid array bound n

Summary:

1) This specific program is compilable w/o a cycle since unsafe.Sizeof(x) doesn't need
to look into the internals of the interface type of x. That said, the spec doesn't say
anything about it, and one might argue that it's ok for a compiler to not handle this
esoteric case. However, 6g is inconsistent in this respect here.

2) Package-level declarations do not depend on source order. The behavior of the
compiler (error or not) should not depend on it either.

(gccgo accepts all programs w/o errors).
@remyoudompheng

This comment has been minimized.

Copy link
Contributor

commented Oct 15, 2013

Comment 1:

I think "typechecking loop" is an internal compiler error and should never happen anyway.
@rsc

This comment has been minimized.

Copy link
Contributor

commented Nov 27, 2013

Comment 2:

Labels changed: added go1.3maybe.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Dec 4, 2013

Comment 3:

Labels changed: added release-none, removed go1.3maybe.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Dec 4, 2013

Comment 4:

Labels changed: added repo-main.

@rsc rsc removed the compiler-bug label Apr 10, 2015

@rsc rsc added this to the Unplanned milestone Apr 10, 2015

@rsc rsc removed release-none labels Apr 10, 2015

@rsc rsc changed the title cmd/gc: odd/inconsistent behavior with cyclic declarations cmd/compile: odd/inconsistent behavior with cyclic declarations Jun 8, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.