Commit d5e47fdc authored by Robert Griesemer's avatar Robert Griesemer

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/84898Reviewed-by: 's avatarAlan Donovan <adonovan@google.com>
parent cf12fef5
......@@ -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()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment