// Do not use casually!
FakeImportC bool
+ // If CompilerErrorMessages is set, errors are reported using
+ // cmd/compile error strings to match $GOROOT/test errors.
+ // TODO(gri) Consolidate error messages and remove this flag.
+ CompilerErrorMessages bool
+
// If go115UsesCgo is set, the type checker expects the
// _cgo_gotypes.go file generated by running cmd/cgo to be
// provided as a package source file. Qualified identifiers
// values
{`package v0; var (a, b int; _ = a + b)`, `a + b`, `value`},
- {`package v1; var _ = &[]int{1}`, `([]int literal)`, `value`},
- {`package v2; var _ = func(){}`, `(func() literal)`, `value`},
+ {`package v1; var _ = &[]int{1}`, `[]int{…}`, `value`},
+ {`package v2; var _ = func(){}`, `func() {}`, `value`},
{`package v4; func f() { _ = f }`, `f`, `value`},
{`package v3; var _ *int = nil`, `nil`, `value, nil`},
{`package v3; var _ *int = (nil)`, `(nil)`, `value, nil`},
"z = 0", "a, b = f()",
}},
{`package p7; var (a = func() int { return b }(); b = 1)`, []string{
- "b = 1", "a = (func() int literal)()",
+ "b = 1", "a = func() int {…}()",
}},
{`package p8; var (a, b = func() (_, _ int) { return c, c }(); c = 1)`, []string{
- "c = 1", "a, b = (func() (_, _ int) literal)()",
+ "c = 1", "a, b = func() (_, _ int) {…}()",
}},
{`package p9; type T struct{}; func (T) m() int { _ = y; return 0 }; var x, y = T.m, 1`, []string{
"y = 1", "x = T.m",
}
if reason := ""; !x.assignableTo(check, T, &reason) {
- if reason != "" {
- check.errorf(x, "cannot use %s as %s value in %s: %s", x, T, context, reason)
+ if check.conf.CompilerErrorMessages {
+ check.errorf(x, "incompatible type: cannot use %s as %s value", x, T)
} else {
- check.errorf(x, "cannot use %s as %s value in %s", x, T, context)
+ if reason != "" {
+ check.errorf(x, "cannot use %s as %s value in %s: %s", x, T, context, reason)
+ } else {
+ check.errorf(x, "cannot use %s as %s value in %s", x, T, context)
+ }
}
x.mode = invalid
}
// both argument types must be identical
if !check.identical(x.typ, y.typ) {
- check.invalidArgf(x, "mismatched types %s and %s", x.typ, y.typ)
+ check.invalidOpf(x, "%s (mismatched types %s and %s)", call, x.typ, y.typ)
return
}
case *Var:
check.errorf(m.pos, "field and method with the same name %s", m.name)
case *Func:
- check.errorf(m.pos, "method %s already declared for %s", m.name, obj)
+ if check.conf.CompilerErrorMessages {
+ check.errorf(m.pos, "%s.%s redeclared in this block", obj.Name(), m.name)
+ } else {
+ check.errorf(m.pos, "method %s already declared for %s", m.name, obj)
+ }
default:
unreachable()
}
}
if err != "" {
- check.errorf(x, "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
+ // TODO(gri) better error message for cases where one can only compare against nil
+ check.invalidOpf(x, "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
x.mode = invalid
return
}
goto Error
case *syntax.BasicLit:
+ if e.Bad {
+ goto Error // error was reported before
+ }
x.setConst(e.Kind, e.Value)
if x.mode == invalid {
// The parser already establishes syntactic correctness.
valid = true
length = typ.len
if x.mode != variable {
- check.invalidOpf(x, "cannot slice %s (value not addressable)", x)
+ check.invalidOpf(x, "%s (slice of unaddressable value)", x)
goto Error
}
x.typ = &Slice{elem: typ.elem}
buf.WriteString(x.Value)
case *syntax.FuncLit:
- buf.WriteByte('(')
WriteExpr(buf, x.Type)
- buf.WriteString(" literal)") // shortened
+ if x.Body != nil && len(x.Body.List) > 0 {
+ buf.WriteString(" {…}") // shortened
+ } else {
+ buf.WriteString(" {}")
+ }
case *syntax.CompositeLit:
- buf.WriteByte('(')
WriteExpr(buf, x.Type)
- buf.WriteString(" literal)") // shortened
+ if len(x.ElemList) > 0 {
+ buf.WriteString("{…}") // shortened
+ } else {
+ buf.WriteString("{}")
+ }
case *syntax.ParenExpr:
buf.WriteByte('(')
dup("`bar`"),
// func and composite literals
- {"func(){}", "(func() literal)"},
- {"func(x int) complex128 {}", "(func(x int) complex128 literal)"},
- {"[]int{1, 2, 3}", "([]int literal)"},
+ {"func(){}", "func() {}"},
+ {"func(x int) complex128 {}", "func(x int) complex128 {}"},
+ {"[]int{1, 2, 3}", "[]int{…}"},
// non-type expressions
dup("(x)"),
_ = S2{}.B
_ = S2{}.C
_ = S2{}.D /* ERROR "no field or method" */
- _ = S3{}.S1 /* ERROR "ambiguous selector \(S3 literal\).S1" */
+ _ = S3{}.S1 /* ERROR "ambiguous selector S3\{\}.S1" */
_ = S3{}.A
- _ = S3{}.B /* ERROR "ambiguous selector" \(S3 literal\).B */
+ _ = S3{}.B /* ERROR "ambiguous selector" S3\{\}.B */
_ = S3{}.D
_ = S3{}.E
_ = S4{}.A
_ = S4{}.B /* ERROR "no field or method" */
- _ = S5{}.X /* ERROR "ambiguous selector \(S5 literal\).X" */
+ _ = S5{}.X /* ERROR "ambiguous selector S5\{\}.X" */
_ = S5{}.Y
- _ = S10{}.X /* ERROR "ambiguous selector \(S10 literal\).X" */
+ _ = S10{}.X /* ERROR "ambiguous selector S10\{\}.X" */
_ = S10{}.Y
}
type R23 R21
type R24 R21
-var _ = R0{}.X /* ERROR "ambiguous selector \(R0 literal\).X" */
\ No newline at end of file
+var _ = R0{}.X /* ERROR "ambiguous selector R0\{\}.X" */
\ No newline at end of file
}
var (
- _ = eD{}.xf /* ERROR ambiguous selector \(eD literal\).xf */
- _ = eD{}.xm /* ERROR ambiguous selector \(eD literal\).xm */
+ _ = eD{}.xf /* ERROR ambiguous selector eD\{\}.xf */
+ _ = eD{}.xm /* ERROR ambiguous selector eD\{\}.xm */
)
var (
T11 = T
)
-func (T9 /* ERROR invalid receiver \*\*T */ ) m9() {}
+func (T9 /* ERROR invalid receiver type \*\*T */ ) m9() {}
func _() { (T{}).m9 /* ERROR has no field or method m9 */ () }
func _() { (&T{}).m9 /* ERROR has no field or method m9 */ () }
// as the method."
if T.obj.pkg != check.pkg {
err = "type not defined in this package"
+ if check.conf.CompilerErrorMessages {
+ check.errorf(recv.pos, "cannot define new methods on non-local type %s", recv.typ)
+ err = ""
+ }
} else {
switch u := optype(T.Under()).(type) {
case *Basic:
err = "pointer or interface type"
}
}
- } else {
+ } else if T := t.Basic(); T != nil {
err = "basic or unnamed type"
+ if check.conf.CompilerErrorMessages {
+ check.errorf(recv.pos, "cannot define new methods on non-local type %s", recv.typ)
+ err = ""
+ }
+ } else {
+ check.errorf(recv.pos, "invalid receiver type %s", recv.typ)
}
if err != "" {
- check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err)
+ check.errorf(recv.pos, "invalid receiver type %s (%s)", recv.typ, err)
// ok to continue
}
}