mirror of
https://github.com/golang/go
synced 2024-10-02 14:28:38 -06:00
go/types: perform delayed tests even for types.Eval
R=go1.11 types.Eval historically never evaluated any delayed tests, which included verification of validity of map keys, but also function literal bodies. Now, embedded interfaces are also type-checked in a delayed fashion, so it becomes imperative to do all delayed checks for eval (otherwise obviously incorrect type expressions are silently accepted). Enabling the delayed tests also removes the restriction that function literals were not type-checked. Also fixed a bug where eval wouldn't return a type-checking error because check.handleBailout was using the wrong err variable. Added tests that verify that method set computation is using the right types when evaluating interfaces with embedded types. For #18395. For #22992. Change-Id: I574fa84568b5158bca4b4ccd4ef5abb616fbf896 Reviewed-on: https://go-review.googlesource.com/84898 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
cf12fef5c6
commit
d5e47fdc92
@ -16,9 +16,6 @@ import (
|
||||
// complete position information relative to the provided file
|
||||
// set.
|
||||
//
|
||||
// If the expression contains function literals, their bodies
|
||||
// are ignored (i.e., the bodies are not type-checked).
|
||||
//
|
||||
// If pkg == nil, the Universe scope is used and the provided
|
||||
// position pos is ignored. If pkg != nil, and pos is invalid,
|
||||
// the package scope is used. Otherwise, pos must belong to the
|
||||
@ -34,7 +31,7 @@ import (
|
||||
// level untyped constants will return an untyped type rather then the
|
||||
// respective context-specific type.
|
||||
//
|
||||
func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (TypeAndValue, error) {
|
||||
func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (_ TypeAndValue, err error) {
|
||||
// determine scope
|
||||
var scope *Scope
|
||||
if pkg == nil {
|
||||
@ -79,5 +76,7 @@ func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (TypeAn
|
||||
// evaluate node
|
||||
var x operand
|
||||
check.rawExpr(&x, node, nil)
|
||||
return TypeAndValue{x.mode, x.typ, x.val}, err
|
||||
check.processDelayed(0) // incl. all functions
|
||||
|
||||
return TypeAndValue{x.mode, x.typ, x.val}, nil
|
||||
}
|
||||
|
@ -149,6 +149,19 @@ func TestEvalPos(t *testing.T) {
|
||||
package p
|
||||
/* T => , p.T */
|
||||
`,
|
||||
`
|
||||
package p
|
||||
import "io"
|
||||
type R = io.Reader
|
||||
func _() {
|
||||
/* interface{R}.Read => , func(interface{io.Reader}, p []byte) (n int, err error) */
|
||||
_ = func() {
|
||||
/* interface{io.Writer}.Write => , func(interface{io.Writer}, p []byte) (n int, err error) */
|
||||
type io interface {} // must not shadow io in line above
|
||||
}
|
||||
type R interface {} // must not shadow R in first line of this function body
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
||||
fset := token.NewFileSet()
|
||||
|
Loading…
Reference in New Issue
Block a user