fix: assert switch type from valueT in struct case (#747)

* fix: switch type from valueT in struct case

In a struct case in type assertion, if the source is a valueT, we still need to take the struct type to allow method and field resolution.

* fix: handle all ptr structs as well
This commit is contained in:
Nicholas Wiersma
2020-07-06 15:09:48 +02:00
committed by GitHub
parent a8b1c2a017
commit 851444453c
3 changed files with 89 additions and 1 deletions

44
_test/type25.go Normal file
View File

@@ -0,0 +1,44 @@
package main
import (
"errors"
"sync/atomic"
)
type wrappedError struct {
wrapped error
}
func (e wrappedError) Error() string {
return "some outer error"
}
func (e wrappedError) Unwrap() error {
return e.wrapped
}
var err atomic.Value
func getWrapped() *wrappedError {
if v := err.Load(); v != nil {
err := v.(wrappedError)
if err.wrapped != nil {
return &err
}
}
return nil
}
func main() {
err.Store(wrappedError{wrapped: errors.New("test")})
e := getWrapped()
if e != nil {
println(e.Error())
println(e.wrapped.Error())
}
}
// Output:
// some outer error
// test

44
_test/type26.go Normal file
View File

@@ -0,0 +1,44 @@
package main
import (
"errors"
"sync/atomic"
)
type wrappedError struct {
wrapped error
}
func (e *wrappedError) Error() string {
return "some outer error"
}
func (e *wrappedError) Unwrap() error {
return e.wrapped
}
var err atomic.Value
func getWrapped() *wrappedError {
if v := err.Load(); v != nil {
err := v.(*wrappedError)
if err.wrapped != nil {
return err
}
}
return nil
}
func main() {
err.Store(&wrappedError{wrapped: errors.New("test")})
e := getWrapped()
if e != nil {
println(e.Error())
println(e.wrapped.Error())
}
}
// Output:
// some outer error
// test

View File

@@ -1715,7 +1715,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
}
}
if n.anc.action != aAssignX {
if n.child[0].typ.cat == valueT {
if n.child[0].typ.cat == valueT && !isStruct(n.child[1].typ) {
// Avoid special wrapping of interfaces and func types.
n.typ = &itype{cat: valueT, rtype: n.child[1].typ.TypeOf()}
} else {