fix: handle interface fields in literal composite structs

Struct fields of type interface must be converted in wrapper
values to be reachable by the runtime. Call genInterfaceWrapper
on such values.

Fixes #832.
This commit is contained in:
Marc Vertes
2020-09-09 13:44:04 +02:00
committed by GitHub
parent 9ddecfa121
commit f1f3ca7e06
3 changed files with 113 additions and 2 deletions

51
_test/cli4.go Normal file
View File

@@ -0,0 +1,51 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
)
type mw1 struct {
next http.Handler
}
func (m *mw1) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
m.next.ServeHTTP(rw, rq)
}
type mw0 struct{}
func (m *mw0) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Welcome to my website!")
}
func main() {
m0 := &mw0{}
m1 := &mw1{m0}
mux := http.NewServeMux()
mux.HandleFunc("/", m1.ServeHTTP)
server := httptest.NewServer(mux)
defer server.Close()
client(server.URL)
}
func client(uri string) {
resp, err := http.Get(uri)
if err != nil {
log.Fatal(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))
}
// Output:
// Welcome to my website!

51
_test/cli5.go Normal file
View File

@@ -0,0 +1,51 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
)
type mw1 struct {
next http.Handler
}
func (m *mw1) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
m.next.ServeHTTP(rw, rq)
}
type mw0 struct{}
func (m *mw0) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Welcome to my website!")
}
func main() {
m0 := &mw0{}
m1 := &mw1{next: m0}
mux := http.NewServeMux()
mux.HandleFunc("/", m1.ServeHTTP)
server := httptest.NewServer(mux)
defer server.Close()
client(server.URL)
}
func client(uri string) {
resp, err := http.Get(uri)
if err != nil {
log.Fatal(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))
}
// Output:
// Welcome to my website!

View File

@@ -2078,9 +2078,16 @@ func doCompositeLit(n *node, hasType bool) {
values := make([]func(*frame) reflect.Value, len(child))
for i, c := range child {
convertLiteralValue(c, typ.field[i].typ.TypeOf())
if c.typ.cat == funcT {
switch {
case c.typ.cat == funcT:
values[i] = genFunctionWrapper(c)
} else {
case isArray(c.typ) && c.typ.val != nil && c.typ.val.cat == interfaceT:
values[i] = genValueInterfaceArray(c)
case isRecursiveType(typ.field[i].typ, typ.field[i].typ.rtype):
values[i] = genValueRecursiveInterface(c, typ.field[i].typ.rtype)
case isInterface(typ.field[i].typ):
values[i] = genInterfaceWrapper(c, typ.field[i].typ.rtype)
default:
values[i] = genValue(c)
}
}
@@ -2134,6 +2141,8 @@ func doCompositeSparse(n *node, hasType bool) {
values[field] = genValueInterfaceArray(c1)
case isRecursiveType(typ.field[field].typ, typ.field[field].typ.rtype):
values[field] = genValueRecursiveInterface(c1, typ.field[field].typ.rtype)
case isInterface(typ.field[field].typ):
values[field] = genInterfaceWrapper(c1, typ.field[field].typ.rtype)
default:
values[field] = genValue(c1)
}