Skip to content

Commit

Permalink
fix: assert switch type from valueT in struct case (#747)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
nrwiersma committed Jul 6, 2020
1 parent a8b1c2a commit 8514444
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
44 changes: 44 additions & 0 deletions _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
44 changes: 44 additions & 0 deletions _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
2 changes: 1 addition & 1 deletion interp/cfg.go
Expand Up @@ -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 {
Expand Down

0 comments on commit 8514444

Please sign in to comment.