Skip to content

Commit

Permalink
fix: handle interface fields in literal composite structs
Browse files Browse the repository at this point in the history
Struct fields of type interface must be converted in wrapper
values to be reachable by the runtime. Call genInterfaceWrapper
on such values.

Fixes #832.
  • Loading branch information
mvertes committed Sep 9, 2020
1 parent 9ddecfa commit f1f3ca7
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
51 changes: 51 additions & 0 deletions _test/cli4.go
@@ -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 changes: 51 additions & 0 deletions _test/cli5.go
@@ -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!
13 changes: 11 additions & 2 deletions interp/run.go
Expand Up @@ -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)
}
}
Expand Down Expand Up @@ -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)
}
Expand Down

0 comments on commit f1f3ca7

Please sign in to comment.