1
0
mirror of https://github.com/golang/go synced 2024-10-02 16:28:34 -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:
Robert Griesemer 2017-12-19 15:45:50 -08:00
parent cf12fef5c6
commit d5e47fdc92
2 changed files with 17 additions and 5 deletions

View File

@ -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
}

View File

@ -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()