Merge lp:~mwhudson/juju-core/gccgo-reflection-fun into lp:~go-bot/juju-core/trunk

Proposed by John A Meinel
Status: Rejected
Rejected by: John A Meinel
Proposed branch: lp:~mwhudson/juju-core/gccgo-reflection-fun
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 128 lines (+33/-7)
4 files modified
rpc/reflect_test.go (+3/-0)
rpc/rpc_test.go (+15/-4)
rpc/rpcreflect/type.go (+12/-2)
state/apiserver/root.go (+3/-1)
To merge this branch: bzr merge lp:~mwhudson/juju-core/gccgo-reflection-fun
Reviewer Review Type Date Requested Status
John A Meinel Approve
Review via email: mp+195717@code.launchpad.net

Commit message

Change RPC methods to not return empty structs.
Empty structs cause gccgo to panic, so instead we use struct { _ bool } to ensure they are not empty.

Description of the change

This fixes the linked bug and makes attempting to return a structure fail. I expect this will confusingly break other parts of Juju...

To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

Resubmitting seems to have sorted Launchpad out. Now on to review.

Revision history for this message
John A Meinel (jameinel) wrote :

67 +type newlyAvailableMethods struct {
68 + _ bool
69 +}

I think for each of these we probably want to explain why we're doing it, referencing the related bug.

Something like:
67 +type newlyAvailableMethods struct {
68 + _ bool // gccgo Reflect breaks on empty structs: https://bugs.launchpad.net/juju-core/+bug/1251076
69 +}

Just poke me when you feel this is ready to land. I'm happy with just some doc tweaks.

review: Approve
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

John A Meinel <email address hidden> writes:

> Review: Approve
>
> 67 +type newlyAvailableMethods struct {
> 68 + _ bool
> 69 +}
>
> I think for each of these we probably want to explain why we're doing it, referencing the related bug.
>
> Something like:
> 67 +type newlyAvailableMethods struct {
> 68 + _ bool // gccgo Reflect breaks on empty structs: https://bugs.launchpad.net/juju-core/+bug/1251076
> 69 +}
>
> Just poke me when you feel this is ready to land. I'm happy with just some doc tweaks.

I think this is fine to land now.

That said, there are other gccgo fixes required to make gccgo and juju
play nice together and we're going to be providing a PPA with this and
those other fixes in it for at least saucy... so maybe this doesn't
actually need to land at all? If this happens, I'm sorry for wasting
your time!

Revision history for this message
Go Bot (go-bot) wrote :

Attempt to merge into lp:juju-core failed due to conflicts:

text conflict in state/apiserver/root.go

Revision history for this message
Go Bot (go-bot) wrote :

Attempt to merge into lp:juju-core failed due to conflicts:

text conflict in state/apiserver/root.go

Revision history for this message
John A Meinel (jameinel) wrote :

I'm pretty sure we decided we don't need this after all, so marking it rejected.

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

John A Meinel <email address hidden> writes:

> I'm pretty sure we decided we don't need this after all, so marking it rejected.

Yes indeed. Sorry for not withdrawing this when that became clear.

Unmerged revisions

2076. By Michael Hudson-Doyle

another workaround field

2075. By Michael Hudson-Doyle

add workaround fields

2074. By Michael Hudson-Doyle

discard methods taking or returning empty structures

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'rpc/reflect_test.go'
2--- rpc/reflect_test.go 2013-09-23 10:06:47 +0000
3+++ rpc/reflect_test.go 2013-11-19 07:42:22 +0000
4@@ -28,6 +28,7 @@
5 "Discard1",
6 "Discard2",
7 "Discard3",
8+ "Discard4",
9 })
10 expect := map[string]reflect.Type{
11 "CallbackMethods": reflect.TypeOf(&CallbackMethods{}),
12@@ -58,6 +59,8 @@
13 "Discard2",
14 "Discard3",
15 "Discard4",
16+ "Discard5",
17+ "Discard6",
18 })
19 expect := map[string]*rpcreflect.ObjMethod{
20 "SliceArg": {
21
22=== modified file 'rpc/rpc_test.go'
23--- rpc/rpc_test.go 2013-10-25 18:21:30 +0000
24+++ rpc/rpc_test.go 2013-11-19 07:42:22 +0000
25@@ -95,6 +95,8 @@
26
27 func (r *Root) Discard3(id string) int { return 0 }
28
29+func (r *Root) Discard4(id string) (_ struct {}, _ error) { return }
30+
31 func (r *Root) CallbackMethods(string) (*CallbackMethods, error) {
32 return &CallbackMethods{r}, nil
33 }
34@@ -183,11 +185,16 @@
35
36 func (a *SimpleMethods) Discard1(int) {}
37
38-func (a *SimpleMethods) Discard2(struct{}, struct{}) {}
39+func (a *SimpleMethods) Discard2(struct{ _ bool }, struct{ _ bool }) {}
40
41 func (a *SimpleMethods) Discard3() int { return 0 }
42
43-func (a *SimpleMethods) Discard4() (_, _ struct{}) { return }
44+func (a *SimpleMethods) Discard4() (_, _ struct{ _ bool }) { return }
45+
46+func (a *SimpleMethods) Discard5(struct {}) { return }
47+
48+func (a *SimpleMethods) Discard6() (_ struct {}) { return }
49+
50
51 type DelayedMethods struct {
52 ready chan struct{}
53@@ -243,13 +250,17 @@
54 a.r.conn.Serve(nil, nil)
55 }
56
57-type changedAPIRoot struct{}
58+type changedAPIRoot struct{
59+ _ bool
60+}
61
62 func (r *changedAPIRoot) NewlyAvailable(string) (newlyAvailableMethods, error) {
63 return newlyAvailableMethods{}, nil
64 }
65
66-type newlyAvailableMethods struct{}
67+type newlyAvailableMethods struct {
68+ _ bool
69+}
70
71 func (newlyAvailableMethods) NewMethod() stringVal {
72 return stringVal{"new method result"}
73
74=== modified file 'rpc/rpcreflect/type.go'
75--- rpc/rpcreflect/type.go 2013-09-24 07:12:05 +0000
76+++ rpc/rpcreflect/type.go 2013-11-19 07:42:22 +0000
77@@ -130,6 +130,13 @@
78 return m.Name == "Kill" && m.Type.NumIn() == 1 && m.Type.NumOut() == 0
79 }
80
81+func isEmptyStruct(t reflect.Type) bool {
82+ // gccgo has a bug calling methods that take or return empty
83+ // structs via reflection. See
84+ // https://code.google.com/p/go/issues/detail?id=6761.
85+ return t.Kind() == reflect.Struct && t.NumField() == 0
86+}
87+
88 func newRootMethod(m reflect.Method) *RootMethod {
89 if m.PkgPath != "" {
90 return nil
91@@ -141,6 +148,9 @@
92 t.Out(1) != errorType {
93 return nil
94 }
95+ if isEmptyStruct(t.Out(0)) {
96+ return nil
97+ }
98 f := func(rcvr reflect.Value, id string) (r reflect.Value, err error) {
99 out := rcvr.Method(m.Index).Call([]reflect.Value{reflect.ValueOf(id)})
100 if !out[1].IsNil() {
101@@ -325,10 +335,10 @@
102 return nil
103 }
104 // The parameters and return value must be of struct type.
105- if p.Params != nil && p.Params.Kind() != reflect.Struct {
106+ if p.Params != nil && (p.Params.Kind() != reflect.Struct || isEmptyStruct(p.Params)) {
107 return nil
108 }
109- if p.Result != nil && p.Result.Kind() != reflect.Struct {
110+ if p.Result != nil && (p.Result.Kind() != reflect.Struct || isEmptyStruct(p.Result)) {
111 return nil
112 }
113 return &p
114
115=== modified file 'state/apiserver/root.go'
116--- state/apiserver/root.go 2013-10-11 09:56:04 +0000
117+++ state/apiserver/root.go 2013-11-19 07:42:22 +0000
118@@ -233,7 +233,9 @@
119 return srvPinger{}, nil
120 }
121
122-type srvPinger struct{}
123+type srvPinger struct {
124+ _ bool // see https://code.google.com/p/go/issues/detail?id=6761
125+}
126
127 // Ping is a no-op used by client heartbeat monitor.
128 func (r srvPinger) Ping() {}

Subscribers

People subscribed via source and target branches

to status/vote changes: