diff --git a/_test/type25.go b/_test/type25.go new file mode 100644 index 000000000..dad1fc537 --- /dev/null +++ b/_test/type25.go @@ -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 diff --git a/_test/type26.go b/_test/type26.go new file mode 100644 index 000000000..de4187d76 --- /dev/null +++ b/_test/type26.go @@ -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 diff --git a/interp/cfg.go b/interp/cfg.go index e2eb220e9..a530c25e6 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -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 {