Commit 3d91624f authored by Robert Griesemer's avatar Robert Griesemer

go/types: unified handling of assignment errors

- simpler code
- closer to gc error messages
- more context information in some cases

Change-Id: Iad155a887b838a4fc1edf719eed18269670b5ede
Reviewed-on: https://go-review.googlesource.com/14720Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 3f08151e
...@@ -797,7 +797,7 @@ func main() { ...@@ -797,7 +797,7 @@ func main() {
makePkg("main", mainSrc) makePkg("main", mainSrc)
for e, sel := range selections { for e, sel := range selections {
sel.String() // assertion: must not panic _ = sel.String() // assertion: must not panic
start := fset.Position(e.Pos()).Offset start := fset.Position(e.Pos()).Offset
end := fset.Position(e.End()).Offset end := fset.Position(e.End()).Offset
......
...@@ -13,17 +13,15 @@ import ( ...@@ -13,17 +13,15 @@ import (
// assignment reports whether x can be assigned to a variable of type T, // assignment reports whether x can be assigned to a variable of type T,
// if necessary by attempting to convert untyped values to the appropriate // if necessary by attempting to convert untyped values to the appropriate
// type. If x.mode == invalid upon return, then assignment has already // type. context describes the context in which the assignment takes place.
// issued an error message and the caller doesn't have to report another.
// Use T == nil to indicate assignment to an untyped blank identifier. // Use T == nil to indicate assignment to an untyped blank identifier.
// If the result is false and a non-nil reason is provided, it may be set // x.mode is set to invalid if the assignment failed.
// to a more detailed explanation of the failure (result != ""). func (check *Checker) assignment(x *operand, T Type, context string) {
func (check *Checker) assignment(x *operand, T Type, reason *string) bool {
check.singleValue(x) check.singleValue(x)
switch x.mode { switch x.mode {
case invalid: case invalid:
return true // error reported before return // error reported before
case constant_, variable, mapindex, value, commaok: case constant_, variable, mapindex, value, commaok:
// ok // ok
default: default:
...@@ -39,15 +37,15 @@ func (check *Checker) assignment(x *operand, T Type, reason *string) bool { ...@@ -39,15 +37,15 @@ func (check *Checker) assignment(x *operand, T Type, reason *string) bool {
// or string constant." // or string constant."
if T == nil || IsInterface(T) { if T == nil || IsInterface(T) {
if T == nil && x.typ == Typ[UntypedNil] { if T == nil && x.typ == Typ[UntypedNil] {
check.errorf(x.pos(), "use of untyped nil") check.errorf(x.pos(), "use of untyped nil in %s", context)
x.mode = invalid x.mode = invalid
return false return
} }
target = defaultType(x.typ) target = defaultType(x.typ)
} }
check.convertUntyped(x, target) check.convertUntyped(x, target)
if x.mode == invalid { if x.mode == invalid {
return false return
} }
} }
// x.typ is typed // x.typ is typed
...@@ -55,7 +53,18 @@ func (check *Checker) assignment(x *operand, T Type, reason *string) bool { ...@@ -55,7 +53,18 @@ func (check *Checker) assignment(x *operand, T Type, reason *string) bool {
// spec: "If a left-hand side is the blank identifier, any typed or // spec: "If a left-hand side is the blank identifier, any typed or
// non-constant value except for the predeclared identifier nil may // non-constant value except for the predeclared identifier nil may
// be assigned to it." // be assigned to it."
return T == nil || x.assignableTo(check.conf, T, reason) if T == nil {
return
}
if reason := ""; !x.assignableTo(check.conf, T, &reason) {
if reason != "" {
check.errorf(x.pos(), "cannot use %s as %s value in %s: %s", x, T, context, reason)
} else {
check.errorf(x.pos(), "cannot use %s as %s value in %s", x, T, context)
}
x.mode = invalid
}
} }
func (check *Checker) initConst(lhs *Const, x *operand) { func (check *Checker) initConst(lhs *Const, x *operand) {
...@@ -81,18 +90,15 @@ func (check *Checker) initConst(lhs *Const, x *operand) { ...@@ -81,18 +90,15 @@ func (check *Checker) initConst(lhs *Const, x *operand) {
lhs.typ = x.typ lhs.typ = x.typ
} }
if reason := ""; !check.assignment(x, lhs.typ, &reason) { check.assignment(x, lhs.typ, "constant declaration")
if x.mode != invalid { if x.mode == invalid {
check.xerrorf(x.pos(), reason, "cannot define constant %s (type %s) as %s", lhs.Name(), lhs.typ, x)
}
return return
} }
lhs.val = x.val lhs.val = x.val
} }
// If result is set, lhs is a function result parameter and x is a return result. func (check *Checker) initVar(lhs *Var, x *operand, context string) Type {
func (check *Checker) initVar(lhs *Var, x *operand, result bool) Type {
if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] { if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
if lhs.typ == nil { if lhs.typ == nil {
lhs.typ = Typ[Invalid] lhs.typ = Typ[Invalid]
...@@ -106,7 +112,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, result bool) Type { ...@@ -106,7 +112,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, result bool) Type {
if isUntyped(typ) { if isUntyped(typ) {
// convert untyped types to default types // convert untyped types to default types
if typ == Typ[UntypedNil] { if typ == Typ[UntypedNil] {
check.errorf(x.pos(), "use of untyped nil") check.errorf(x.pos(), "use of untyped nil in %s", context)
lhs.typ = Typ[Invalid] lhs.typ = Typ[Invalid]
return nil return nil
} }
...@@ -115,15 +121,8 @@ func (check *Checker) initVar(lhs *Var, x *operand, result bool) Type { ...@@ -115,15 +121,8 @@ func (check *Checker) initVar(lhs *Var, x *operand, result bool) Type {
lhs.typ = typ lhs.typ = typ
} }
if reason := ""; !check.assignment(x, lhs.typ, &reason) { check.assignment(x, lhs.typ, context)
if x.mode != invalid { if x.mode == invalid {
if result {
// don't refer to lhs.name because it may be an anonymous result parameter
check.xerrorf(x.pos(), reason, "cannot return %s as value of type %s", x, lhs.typ)
} else {
check.xerrorf(x.pos(), reason, "cannot initialize %s with %s", lhs, x)
}
}
return nil return nil
} }
...@@ -141,9 +140,9 @@ func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type { ...@@ -141,9 +140,9 @@ func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
// Don't evaluate lhs if it is the blank identifier. // Don't evaluate lhs if it is the blank identifier.
if ident != nil && ident.Name == "_" { if ident != nil && ident.Name == "_" {
check.recordDef(ident, nil) check.recordDef(ident, nil)
if !check.assignment(x, nil, nil) { check.assignment(x, nil, "assignment to _ identifier")
assert(x.mode == invalid) if x.mode == invalid {
x.typ = nil return nil
} }
return x.typ return x.typ
} }
...@@ -184,10 +183,8 @@ func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type { ...@@ -184,10 +183,8 @@ func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
return nil return nil
} }
if reason := ""; !check.assignment(x, z.typ, &reason) { check.assignment(x, z.typ, "assignment")
if x.mode != invalid { if x.mode == invalid {
check.xerrorf(x.pos(), reason, "cannot assign %s to %s", x, &z)
}
return nil return nil
} }
...@@ -218,12 +215,17 @@ func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) ...@@ -218,12 +215,17 @@ func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos)
return return
} }
context := "assignment"
if returnPos.IsValid() {
context = "return statement"
}
var x operand var x operand
if commaOk { if commaOk {
var a [2]Type var a [2]Type
for i := range a { for i := range a {
get(&x, i) get(&x, i)
a[i] = check.initVar(lhs[i], &x, returnPos.IsValid()) a[i] = check.initVar(lhs[i], &x, context)
} }
check.recordCommaOkTypes(rhs[0], a) check.recordCommaOkTypes(rhs[0], a)
return return
...@@ -231,7 +233,7 @@ func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) ...@@ -231,7 +233,7 @@ func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos)
for i, lhs := range lhs { for i, lhs := range lhs {
get(&x, i) get(&x, i)
check.initVar(lhs, &x, returnPos.IsValid()) check.initVar(lhs, &x, context)
} }
} }
......
...@@ -471,8 +471,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b ...@@ -471,8 +471,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
case _Panic: case _Panic:
// panic(x) // panic(x)
T := new(Interface) T := new(Interface)
if !check.assignment(x, T, nil) { check.assignment(x, T, "argument to panic")
assert(x.mode == invalid) if x.mode == invalid {
return return
} }
...@@ -491,8 +491,9 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b ...@@ -491,8 +491,9 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
if i > 0 { if i > 0 {
arg(x, i) // first argument already evaluated arg(x, i) // first argument already evaluated
} }
if !check.assignment(x, nil, nil) { check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
assert(x.mode == invalid) if x.mode == invalid {
// TODO(gri) "use" all arguments?
return return
} }
params[i] = x.typ params[i] = x.typ
...@@ -514,8 +515,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b ...@@ -514,8 +515,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
case _Alignof: case _Alignof:
// unsafe.Alignof(x T) uintptr // unsafe.Alignof(x T) uintptr
if !check.assignment(x, nil, nil) { check.assignment(x, nil, "argument to unsafe.Alignof")
assert(x.mode == invalid) if x.mode == invalid {
return return
} }
...@@ -571,8 +572,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b ...@@ -571,8 +572,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
case _Sizeof: case _Sizeof:
// unsafe.Sizeof(x T) uintptr // unsafe.Sizeof(x T) uintptr
if !check.assignment(x, nil, nil) { check.assignment(x, nil, "argument to unsafe.Sizeof")
assert(x.mode == invalid) if x.mode == invalid {
return return
} }
......
...@@ -202,7 +202,7 @@ func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, ...@@ -202,7 +202,7 @@ func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature,
if i == n-1 && call.Ellipsis.IsValid() { if i == n-1 && call.Ellipsis.IsValid() {
ellipsis = call.Ellipsis ellipsis = call.Ellipsis
} }
check.argument(sig, i, x, ellipsis) check.argument(call.Fun, sig, i, x, ellipsis)
} }
} }
...@@ -220,7 +220,7 @@ func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, ...@@ -220,7 +220,7 @@ func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature,
// argument checks passing of argument x to the i'th parameter of the given signature. // argument checks passing of argument x to the i'th parameter of the given signature.
// If ellipsis is valid, the argument is followed by ... at that position in the call. // If ellipsis is valid, the argument is followed by ... at that position in the call.
func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token.Pos) { func (check *Checker) argument(fun ast.Expr, sig *Signature, i int, x *operand, ellipsis token.Pos) {
check.singleValue(x) check.singleValue(x)
if x.mode == invalid { if x.mode == invalid {
return return
...@@ -260,9 +260,7 @@ func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token ...@@ -260,9 +260,7 @@ func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token
typ = typ.(*Slice).elem typ = typ.(*Slice).elem
} }
if reason := ""; !check.assignment(x, typ, &reason) && x.mode != invalid { check.assignment(x, typ, check.sprintf("argument to %s", fun))
check.xerrorf(x.pos(), reason, "cannot pass argument %s to parameter of type %s", x, typ)
}
} }
func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
......
...@@ -156,7 +156,7 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { ...@@ -156,7 +156,7 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
assert(lhs == nil || lhs[0] == obj) assert(lhs == nil || lhs[0] == obj)
var x operand var x operand
check.expr(&x, init) check.expr(&x, init)
check.initVar(obj, &x, false) check.initVar(obj, &x, "variable declaration")
return return
} }
......
...@@ -86,14 +86,6 @@ func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) ...@@ -86,14 +86,6 @@ func (check *Checker) errorf(pos token.Pos, format string, args ...interface{})
check.err(pos, check.sprintf(format, args...), false) check.err(pos, check.sprintf(format, args...), false)
} }
func (check *Checker) xerrorf(pos token.Pos, reason, format string, args ...interface{}) {
if reason != "" {
format += ": %s"
args = append(args, reason)
}
check.err(pos, check.sprintf(format, args...), true)
}
func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) { func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) {
check.err(pos, check.sprintf(format, args...), true) check.err(pos, check.sprintf(format, args...), true)
} }
......
...@@ -898,9 +898,7 @@ func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 ...@@ -898,9 +898,7 @@ func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64
// check element against composite literal element type // check element against composite literal element type
var x operand var x operand
check.exprWithHint(&x, eval, typ) check.exprWithHint(&x, eval, typ)
if reason := ""; !check.assignment(&x, typ, &reason) && x.mode != invalid { check.assignment(&x, typ, "array or slice literal")
check.xerrorf(x.pos(), reason, "cannot use %s as %s value in array or slice literal", &x, typ)
}
} }
return max return max
} }
...@@ -1062,12 +1060,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { ...@@ -1062,12 +1060,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
visited[i] = true visited[i] = true
check.expr(x, kv.Value) check.expr(x, kv.Value)
etyp := fld.typ etyp := fld.typ
if reason := ""; !check.assignment(x, etyp, &reason) { check.assignment(x, etyp, "struct literal")
if x.mode != invalid {
check.xerrorf(x.pos(), reason, "cannot use %s as %s value in struct literal", x, etyp)
}
continue
}
} }
} else { } else {
// no element must have a key // no element must have a key
...@@ -1088,12 +1081,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { ...@@ -1088,12 +1081,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
continue continue
} }
etyp := fld.typ etyp := fld.typ
if reason := ""; !check.assignment(x, etyp, &reason) { check.assignment(x, etyp, "struct literal")
if x.mode != invalid {
check.xerrorf(x.pos(), reason, "cannot use %s as %s value in struct literal", x, etyp)
}
continue
}
} }
if len(e.Elts) < len(fields) { if len(e.Elts) < len(fields) {
check.error(e.Rbrace, "too few values in struct literal") check.error(e.Rbrace, "too few values in struct literal")
...@@ -1120,10 +1108,8 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { ...@@ -1120,10 +1108,8 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
continue continue
} }
check.exprWithHint(x, kv.Key, utyp.key) check.exprWithHint(x, kv.Key, utyp.key)
if reason := ""; !check.assignment(x, utyp.key, &reason) { check.assignment(x, utyp.key, "map literal")
if x.mode != invalid { if x.mode == invalid {
check.xerrorf(x.pos(), reason, "cannot use %s as %s key in map literal", x, utyp.key)
}
continue continue
} }
if x.mode == constant_ { if x.mode == constant_ {
...@@ -1147,12 +1133,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { ...@@ -1147,12 +1133,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
} }
} }
check.exprWithHint(x, kv.Value, utyp.elem) check.exprWithHint(x, kv.Value, utyp.elem)
if reason := ""; !check.assignment(x, utyp.elem, &reason) { check.assignment(x, utyp.elem, "map literal")
if x.mode != invalid {
check.xerrorf(x.pos(), reason, "cannot use %s as %s value in map literal", x, utyp.elem)
}
continue
}
} }
default: default:
...@@ -1220,10 +1201,8 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { ...@@ -1220,10 +1201,8 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
case *Map: case *Map:
var key operand var key operand
check.expr(&key, e.Index) check.expr(&key, e.Index)
if reason := ""; !check.assignment(&key, typ.key, &reason) { check.assignment(&key, typ.key, "map index")
if key.mode != invalid { if x.mode == invalid {
check.xerrorf(key.pos(), reason, "cannot use %s as map index of type %s", &key, typ.key)
}
goto Error goto Error
} }
x.mode = mapindex x.mode = mapindex
......
...@@ -321,13 +321,20 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { ...@@ -321,13 +321,20 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
if ch.mode == invalid || x.mode == invalid { if ch.mode == invalid || x.mode == invalid {
return return
} }
reason := ""
if tch, ok := ch.typ.Underlying().(*Chan); !ok || tch.dir == RecvOnly || !check.assignment(&x, tch.elem, &reason) { tch, ok := ch.typ.Underlying().(*Chan)
if x.mode != invalid { if !ok {
check.xerrorf(x.pos(), reason, "cannot send %s to channel %s", &x, &ch) check.invalidOp(s.Arrow, "cannot send to non-chan type %s", ch.typ)
} return
} }
if tch.dir == RecvOnly {
check.invalidOp(s.Arrow, "cannot send to receive-only type %s", tch)
return
}
check.assignment(&x, tch.elem, "send")
case *ast.IncDecStmt: case *ast.IncDecStmt:
var op token.Token var op token.Token
switch s.Tok { switch s.Tok {
...@@ -465,7 +472,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { ...@@ -465,7 +472,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
check.expr(&x, s.Tag) check.expr(&x, s.Tag)
// By checking assignment of x to an invisible temporary // By checking assignment of x to an invisible temporary
// (as a compiler would), we get all the relevant checks. // (as a compiler would), we get all the relevant checks.
check.assignment(&x, nil, nil) check.assignment(&x, nil, "switch expression")
} else { } else {
// spec: "A missing switch expression is // spec: "A missing switch expression is
// equivalent to the boolean value true." // equivalent to the boolean value true."
...@@ -767,7 +774,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { ...@@ -767,7 +774,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
x.mode = value x.mode = value
x.expr = lhs // we don't have a better rhs expression to use here x.expr = lhs // we don't have a better rhs expression to use here
x.typ = typ x.typ = typ
check.initVar(obj, &x, false) check.initVar(obj, &x, "range clause")
} else { } else {
obj.typ = Typ[Invalid] obj.typ = Typ[Invalid]
obj.used = true // don't complain about unused variable obj.used = true // don't complain about unused variable
......
...@@ -22,12 +22,12 @@ func append1() { ...@@ -22,12 +22,12 @@ func append1() {
append /* ERROR not used */ (s) append /* ERROR not used */ (s)
_ = append(s, b) _ = append(s, b)
_ = append(s, x /* ERROR cannot pass argument x */ ) _ = append(s, x /* ERROR cannot use x */ )
_ = append(s, s /* ERROR cannot pass argument s */ ) _ = append(s, s /* ERROR cannot use s */ )
_ = append(s... /* ERROR can only use ... with matching parameter */ ) _ = append(s... /* ERROR can only use ... with matching parameter */ )
_ = append(s, b, s... /* ERROR can only use ... with matching parameter */ ) _ = append(s, b, s... /* ERROR can only use ... with matching parameter */ )
_ = append(s, 1, 2, 3) _ = append(s, 1, 2, 3)
_ = append(s, 1, 2, 3, x /* ERROR cannot pass argument x */ , 5, 6, 6) _ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6)
_ = append(s, 1, 2, s... /* ERROR can only use ... with matching parameter */ ) _ = append(s, 1, 2, s... /* ERROR can only use ... with matching parameter */ )
_ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false) _ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false)
...@@ -38,13 +38,13 @@ func append1() { ...@@ -38,13 +38,13 @@ func append1() {
_ = append(s, "foo"...) _ = append(s, "foo"...)
_ = append(S(s), "foo" /* ERROR cannot convert */ ) _ = append(S(s), "foo" /* ERROR cannot convert */ )
_ = append(S(s), "foo"...) _ = append(S(s), "foo"...)
_ = append(s, t /* ERROR cannot pass argument t */ ) _ = append(s, t /* ERROR cannot use t */ )
_ = append(s, t...) _ = append(s, t...)
_ = append(s, T("foo")...) _ = append(s, T("foo")...)
_ = append(S(s), t /* ERROR cannot pass argument t */ ) _ = append(S(s), t /* ERROR cannot use t */ )
_ = append(S(s), t...) _ = append(S(s), t...)
_ = append(S(s), T("foo")...) _ = append(S(s), T("foo")...)
_ = append([]string{}, t /* ERROR cannot pass argument t */ , "foo") _ = append([]string{}, t /* ERROR cannot use t */ , "foo")
_ = append([]T{}, t, "foo") _ = append([]T{}, t, "foo")
} }
...@@ -192,9 +192,9 @@ func complex1() { ...@@ -192,9 +192,9 @@ func complex1() {
complex /* ERROR not used */ (1, 2) complex /* ERROR not used */ (1, 2)
var _ complex64 = complex(f32, f32) var _ complex64 = complex(f32, f32)
var _ complex64 = complex /* ERROR cannot initialize */ (f64, f64) var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64)
var _ complex128 = complex /* ERROR cannot initialize */ (f32, f32) var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32)
var _ complex128 = complex(f64, f64) var _ complex128 = complex(f64, f64)
// untyped constants // untyped constants
...@@ -213,7 +213,7 @@ func complex1() { ...@@ -213,7 +213,7 @@ func complex1() {
var s uint var s uint
_ = complex(1 /* ERROR integer */ <<s, 0) _ = complex(1 /* ERROR integer */ <<s, 0)
const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0) const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0)
var _ int = complex /* ERROR cannot initialize */ (1 /* ERROR integer */ <<s, 0) var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0)
// floating-point argument types must be identical // floating-point argument types must be identical
type F32 float32 type F32 float32
...@@ -319,8 +319,8 @@ func imag1() { ...@@ -319,8 +319,8 @@ func imag1() {
assert(_6 == 0) assert(_6 == 0)
f32 = imag(c64) f32 = imag(c64)
f64 = imag(c128) f64 = imag(c128)
f32 = imag /* ERROR cannot assign */ (c128) f32 = imag /* ERROR cannot use .* in assignment */ (c128)
f64 = imag /* ERROR cannot assign */ (c64) f64 = imag /* ERROR cannot use .* in assignment */ (c64)
imag /* ERROR not used */ (c64) imag /* ERROR not used */ (c64)
_, _ = f32, f64 _, _ = f32, f64
...@@ -599,8 +599,8 @@ func real1() { ...@@ -599,8 +599,8 @@ func real1() {
assert(_6 == 0) assert(_6 == 0)
f32 = real(c64) f32 = real(c64)
f64 = real(c128) f64 = real(c128)
f32 = real /* ERROR cannot assign */ (c128) f32 = real /* ERROR cannot use .* in assignment */ (c128)
f64 = real /* ERROR cannot assign */ (c64) f64 = real /* ERROR cannot use .* in assignment */ (c64)
real /* ERROR not used */ (c64) real /* ERROR not used */ (c64)
// complex type may not be predeclared // complex type may not be predeclared
......
...@@ -25,7 +25,7 @@ var ( ...@@ -25,7 +25,7 @@ var (
s, t string s, t string
array []byte array []byte
iface interface{} iface interface{}
blank _ /* ERROR "cannot use _" */ blank _ /* ERROR "cannot use _" */
) )
...@@ -43,33 +43,33 @@ var ( ...@@ -43,33 +43,33 @@ var (
s11 = &v s11 = &v
s12 = -(u + *t11) / *&v s12 = -(u + *t11) / *&v
s13 = a /* ERROR "shifted operand" */ << d s13 = a /* ERROR "shifted operand" */ << d
s14 = i << j /* ERROR "must be unsigned" */ s14 = i << j /* ERROR "must be unsigned" */
s18 = math.Pi * 10.0 s18 = math.Pi * 10.0
s19 = s1 /* ERROR "cannot call" */ () s19 = s1 /* ERROR "cannot call" */ ()
s20 = f0 /* ERROR "no value" */ () s20 = f0 /* ERROR "no value" */ ()
s21 = f6(1, s1, i) s21 = f6(1, s1, i)
s22 = f6(1, s1, uu /* ERROR "cannot pass argument" */ ) s22 = f6(1, s1, uu /* ERROR "cannot use .* in argument" */ )
t1 int = i + j t1 int = i + j
t2 int = i /* ERROR "mismatched types" */ + x t2 int = i /* ERROR "mismatched types" */ + x
t3 int = c /* ERROR "cannot initialize" */ + d t3 int = c /* ERROR "cannot use .* variable declaration" */ + d
t4 string = s + t t4 string = s + t
t5 string = s /* ERROR "invalid operation" */ / t t5 string = s /* ERROR "invalid operation" */ / t
t6 byte = array[t1] t6 byte = array[t1]
t7 byte = array[x /* ERROR "must be integer" */] t7 byte = array[x /* ERROR "must be integer" */]
t8 *int = & /* ERROR "cannot initialize" */ a t8 *int = & /* ERROR "cannot use .* variable declaration" */ a
t10 *int = &42 /* ERROR "cannot take address" */ t10 *int = &42 /* ERROR "cannot take address" */
t11 *complex64 = &v t11 *complex64 = &v
t12 complex64 = -(u + *t11) / *&v t12 complex64 = -(u + *t11) / *&v
t13 int = a /* ERROR "shifted operand" */ << d t13 int = a /* ERROR "shifted operand" */ << d
t14 int = i << j /* ERROR "must be unsigned" */ t14 int = i << j /* ERROR "must be unsigned" */
t15 math /* ERROR "not in selector" */ t15 math /* ERROR "not in selector" */
t16 math /* ERROR "not declared" */ .xxx t16 math /* ERROR "not declared" */ .xxx
t17 math /* ERROR "not a type" */ .Pi t17 math /* ERROR "not a type" */ .Pi
t18 float64 = math.Pi * 10.0 t18 float64 = math.Pi * 10.0
t19 int = t1 /* ERROR "cannot call" */ () t19 int = t1 /* ERROR "cannot call" */ ()
t20 int = f0 /* ERROR "no value" */ () t20 int = f0 /* ERROR "no value" */ ()
t21 int = a /* ERROR "cannot initialize" */ t21 int = a /* ERROR "cannot use .* variable declaration" */
) )
// Various more complex expressions // Various more complex expressions
......
...@@ -144,7 +144,7 @@ var ( ...@@ -144,7 +144,7 @@ var (
ch10, ok = <-ch ch10, ok = <-ch
// ok is of type bool // ok is of type bool
ch11, myok = <-ch ch11, myok = <-ch
_ mybool = myok /* ERROR "cannot initialize" */ _ mybool = myok /* ERROR "cannot use .* in variable declaration" */
) )
// address of composite literals // address of composite literals
......
...@@ -28,7 +28,7 @@ func indexes() { ...@@ -28,7 +28,7 @@ func indexes() {
a0 = a[0] a0 = a[0]
_ = a0 _ = a0
var a1 int32 var a1 int32
a1 = a /* ERROR "cannot assign" */ [1] a1 = a /* ERROR "cannot use .* in assignment" */ [1]
_ = a1 _ = a1
_ = a[9] _ = a[9]
...@@ -113,7 +113,7 @@ func indexes() { ...@@ -113,7 +113,7 @@ func indexes() {
t0 = t[0] t0 = t[0]
_ = t0 _ = t0
var t1 rune var t1 rune
t1 = t /* ERROR "cannot assign" */ [2] t1 = t /* ERROR "cannot use .* in assignment" */ [2]
_ = t1 _ = t1
_ = ("foo" + "bar")[5] _ = ("foo" + "bar")[5]
_ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ] _ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ]
...@@ -126,7 +126,7 @@ func indexes() { ...@@ -126,7 +126,7 @@ func indexes() {
c0 = c[0] c0 = c[0]
_ = c0 _ = c0
var c2 float32 var c2 float32
c2 = c /* ERROR "cannot assign" */ [2] c2 = c /* ERROR "cannot use .* in assignment" */ [2]
_ = c[3 /* ERROR "index .* out of bounds" */ ] _ = c[3 /* ERROR "index .* out of bounds" */ ]
_ = ""[0 /* ERROR "index .* out of bounds" */ ] _ = ""[0 /* ERROR "index .* out of bounds" */ ]
_ = c2 _ = c2
...@@ -140,8 +140,8 @@ func indexes() { ...@@ -140,8 +140,8 @@ func indexes() {
var i, j int var i, j int
ss = "foo"[1:2] ss = "foo"[1:2]
ss = "foo"[i:j] ss = "foo"[i:j]
ms = "foo" /* ERROR "cannot assign" */ [1:2] ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2]
ms = "foo" /* ERROR "cannot assign" */ [i:j] ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j]
_, _ = ss, ms _, _ = ss, ms
} }
...@@ -253,7 +253,7 @@ func array_literals() { ...@@ -253,7 +253,7 @@ func array_literals() {
var a13 [3]int var a13 [3]int
var a14 [4]int var a14 [4]int
a13 = a1 a13 = a1
a14 = a1 /* ERROR "cannot assign" */ a14 = a1 /* ERROR "cannot use .* in assignment" */
_, _ = a13, a14 _, _ = a13, a14
a2 := [...]int{- /* ERROR "negative" */ 1: 0} a2 := [...]int{- /* ERROR "negative" */ 1: 0}
...@@ -465,7 +465,7 @@ func _calls() { ...@@ -465,7 +465,7 @@ func _calls() {
f1(10.0) f1(10.0)
f1() /* ERROR "too few arguments" */ f1() /* ERROR "too few arguments" */
f1(x, y /* ERROR "too many arguments" */ ) f1(x, y /* ERROR "too many arguments" */ )
f1(s /* ERROR "cannot pass" */ ) f1(s /* ERROR "cannot use .* in argument" */ )
f1(x ... /* ERROR "cannot use ..." */ ) f1(x ... /* ERROR "cannot use ..." */ )
f1(g0 /* ERROR "used as value" */ ()) f1(g0 /* ERROR "used as value" */ ())
f1(g1()) f1(g1())
...@@ -474,51 +474,51 @@ func _calls() { ...@@ -474,51 +474,51 @@ func _calls() {
f2() /* ERROR "too few arguments" */ f2() /* ERROR "too few arguments" */
f2(3.14) /* ERROR "too few arguments" */ f2(3.14) /* ERROR "too few arguments" */
f2(3.14, "foo") f2(3.14, "foo")
f2(x /* ERROR "cannot pass" */ , "foo") f2(x /* ERROR "cannot use .* in argument" */ , "foo")
f2(g0 /* ERROR "used as value" */ ()) f2(g0 /* ERROR "used as value" */ ())
f2(g1 /* ERROR "cannot pass" */ ()) /* ERROR "too few arguments" */ f2(g1 /* ERROR "cannot use .* in argument" */ ()) /* ERROR "too few arguments" */
f2(g2()) f2(g2())
fs() /* ERROR "too few arguments" */ fs() /* ERROR "too few arguments" */
fs(g0 /* ERROR "used as value" */ ()) fs(g0 /* ERROR "used as value" */ ())
fs(g1 /* ERROR "cannot pass" */ ()) fs(g1 /* ERROR "cannot use .* in argument" */ ())
fs(g2 /* ERROR "cannot pass" */ /* ERROR "too many arguments" */ ()) fs(g2 /* ERROR "cannot use .* in argument" */ /* ERROR "too many arguments" */ ())
fs(gs()) fs(gs())
fv() fv()
fv(1, 2.0, x) fv(1, 2.0, x)
fv(s /* ERROR "cannot pass" */ ) fv(s /* ERROR "cannot use .* in argument" */ )
fv(s...) fv(s...)
fv(x /* ERROR "cannot use" */ ...) fv(x /* ERROR "cannot use" */ ...)
fv(1, s... /* ERROR "can only use ... with matching parameter" */ ) fv(1, s... /* ERROR "can only use ... with matching parameter" */ )
fv(gs /* ERROR "cannot pass" */ ()) fv(gs /* ERROR "cannot use .* in argument" */ ())
fv(gs /* ERROR "cannot pass" */ ()...) fv(gs /* ERROR "cannot use .* in argument" */ ()...)
var t T var t T
t.fm() t.fm()
t.fm(1, 2.0, x) t.fm(1, 2.0, x)
t.fm(s /* ERROR "cannot pass" */ ) t.fm(s /* ERROR "cannot use .* in argument" */ )
t.fm(g1()) t.fm(g1())
t.fm(1, s... /* ERROR "can only use ... with matching parameter" */ ) t.fm(1, s... /* ERROR "can only use ... with matching parameter" */ )
t.fm(gs /* ERROR "cannot pass" */ ()) t.fm(gs /* ERROR "cannot use .* in argument" */ ())
t.fm(gs /* ERROR "cannot pass" */ ()...) t.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
T.fm(t, ) T.fm(t, )
T.fm(t, 1, 2.0, x) T.fm(t, 1, 2.0, x)
T.fm(t, s /* ERROR "cannot pass" */ ) T.fm(t, s /* ERROR "cannot use .* in argument" */ )
T.fm(t, g1()) T.fm(t, g1())
T.fm(t, 1, s... /* ERROR "can only use ... with matching parameter" */ ) T.fm(t, 1, s... /* ERROR "can only use ... with matching parameter" */ )
T.fm(t, gs /* ERROR "cannot pass" */ ()) T.fm(t, gs /* ERROR "cannot use .* in argument" */ ())
T.fm(t, gs /* ERROR "cannot pass" */ ()...) T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...)
var i interface{ fm(x ...int) } = t var i interface{ fm(x ...int) } = t
i.fm() i.fm()
i.fm(1, 2.0, x) i.fm(1, 2.0, x)
i.fm(s /* ERROR "cannot pass" */ ) i.fm(s /* ERROR "cannot use .* in argument" */ )
i.fm(g1()) i.fm(g1())
i.fm(1, s... /* ERROR "can only use ... with matching parameter" */ ) i.fm(1, s... /* ERROR "can only use ... with matching parameter" */ )
i.fm(gs /* ERROR "cannot pass" */ ()) i.fm(gs /* ERROR "cannot use .* in argument" */ ())
i.fm(gs /* ERROR "cannot pass" */ ()...) i.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
fi() fi()
fi(1, 2.0, x, 3.14, "foo") fi(1, 2.0, x, 3.14, "foo")
......
...@@ -52,7 +52,7 @@ func issue9473(a []int, b ...int) { ...@@ -52,7 +52,7 @@ func issue9473(a []int, b ...int) {
_ = append(f0()) _ = append(f0())
_ = append(f0(), f0()...) _ = append(f0(), f0()...)
_ = append(f1()) _ = append(f1())
_ = append(f2 /* ERROR cannot pass argument */ ()) _ = append(f2 /* ERROR cannot use .* in argument */ ())
_ = append(f2()... /* ERROR cannot use ... */ ) _ = append(f2()... /* ERROR cannot use ... */ )
_ = append(f0(), f1 /* ERROR 2-valued f1 */ ()) _ = append(f0(), f1 /* ERROR 2-valued f1 */ ())
_ = append(f0(), f2 /* ERROR 2-valued f2 */ ()) _ = append(f0(), f2 /* ERROR 2-valued f2 */ ())
...@@ -63,7 +63,7 @@ func issue9473(a []int, b ...int) { ...@@ -63,7 +63,7 @@ func issue9473(a []int, b ...int) {
append_(f0()) append_(f0())
append_(f0(), f0()...) append_(f0(), f0()...)
append_(f1()) append_(f1())
append_(f2 /* ERROR cannot pass argument */ ()) append_(f2 /* ERROR cannot use .* in argument */ ())
append_(f2()... /* ERROR cannot use ... */ ) append_(f2()... /* ERROR cannot use ... */ )
append_(f0(), f1 /* ERROR 2-valued f1 */ ()) append_(f0(), f1 /* ERROR 2-valued f1 */ ())
append_(f0(), f2 /* ERROR 2-valued f2 */ ()) append_(f0(), f2 /* ERROR 2-valued f2 */ ())
...@@ -124,24 +124,24 @@ func issue10260() { ...@@ -124,24 +124,24 @@ func issue10260() {
t1 *T1 t1 *T1
t2 *T2 t2 *T2
) )
i1 = i0 /* ERROR cannot assign .* missing method foo */ i1 = i0 /* ERROR cannot use .* missing method foo */
i1 = t0 /* ERROR cannot assign .* missing method foo */ i1 = t0 /* ERROR cannot use .* missing method foo */
i1 = i2 /* ERROR cannot assign .* wrong type for method foo */ i1 = i2 /* ERROR cannot use .* wrong type for method foo */
i1 = t2 /* ERROR cannot assign .* wrong type for method foo */ i1 = t2 /* ERROR cannot use .* wrong type for method foo */
i2 = i1 /* ERROR cannot assign .* wrong type for method foo */ i2 = i1 /* ERROR cannot use .* wrong type for method foo */
i2 = t1 /* ERROR cannot assign .* wrong type for method foo */ i2 = t1 /* ERROR cannot use .* wrong type for method foo */
_ = func() I1 { return i0 /* ERROR cannot return .* missing method foo */ } _ = func() I1 { return i0 /* ERROR cannot use .* missing method foo */ }
_ = func() I1 { return t0 /* ERROR cannot return .* missing method foo */ } _ = func() I1 { return t0 /* ERROR cannot use .* missing method foo */ }
_ = func() I1 { return i2 /* ERROR cannot return .* wrong type for method foo */ } _ = func() I1 { return i2 /* ERROR cannot use .* wrong type for method foo */ }
_ = func() I1 { return t2 /* ERROR cannot return .* wrong type for method foo */ } _ = func() I1 { return t2 /* ERROR cannot use .* wrong type for method foo */ }
_ = func() I2 { return i1 /* ERROR cannot return .* wrong type for method foo */ } _ = func() I2 { return i1 /* ERROR cannot use .* wrong type for method foo */ }
_ = func() I2 { return t1 /* ERROR cannot return .* wrong type for method foo */ } _ = func() I2 { return t1 /* ERROR cannot use .* wrong type for method foo */ }
// a few more - less exhaustive now // a few more - less exhaustive now
f := func(I1, I2){} f := func(I1, I2){}
f(i0 /* ERROR cannot pass .* missing method foo */ , i1 /* ERROR cannot pass .* wrong type for method foo */) f(i0 /* ERROR cannot use .* missing method foo */ , i1 /* ERROR cannot use .* wrong type for method foo */)
_ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ } _ = [...]I1{i0 /* ERROR cannot use .* missing method foo */ }
_ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ } _ = [...]I1{i2 /* ERROR cannot use .* wrong type for method foo */ }
...@@ -150,6 +150,6 @@ func issue10260() { ...@@ -150,6 +150,6 @@ func issue10260() {
_ = map[int]I1{0: i0 /* ERROR cannot use .* missing method foo */ } _ = map[int]I1{0: i0 /* ERROR cannot use .* missing method foo */ }
_ = map[int]I1{0: i2 /* ERROR cannot use .* wrong type for method foo */ } _ = map[int]I1{0: i2 /* ERROR cannot use .* wrong type for method foo */ }
make(chan I1) <- i0 /* ERROR cannot send .* missing method foo */ make(chan I1) <- i0 /* ERROR cannot use .* in send: missing method foo */
make(chan I1) <- i2 /* ERROR cannot send .* wrong type for method foo */ make(chan I1) <- i2 /* ERROR cannot use .* in send: wrong type for method foo */
} }
...@@ -37,11 +37,11 @@ func assignments0() (int, int) { ...@@ -37,11 +37,11 @@ func assignments0() (int, int) {
func assignments1() { func assignments1() {
b, i, f, c, s := false, 1, 1.0, 1i, "foo" b, i, f, c, s := false, 1, 1.0, 1i, "foo"
b = i /* ERROR "cannot assign" */ b = i /* ERROR "cannot use .* in assignment" */
i = f /* ERROR "cannot assign" */ i = f /* ERROR "cannot use .* in assignment" */
f = c /* ERROR "cannot assign" */ f = c /* ERROR "cannot use .* in assignment" */
c = s /* ERROR "cannot assign" */ c = s /* ERROR "cannot use .* in assignment" */
s = b /* ERROR "cannot assign" */ s = b /* ERROR "cannot use .* in assignment" */
v0, v1, v2 := 1 /* ERROR "mismatch" */ , 2, 3, 4 v0, v1, v2 := 1 /* ERROR "mismatch" */ , 2, 3, 4
_, _, _ = v0, v1, v2 _, _, _ = v0, v1, v2
...@@ -180,8 +180,8 @@ func sends() { ...@@ -180,8 +180,8 @@ func sends() {
var ch chan int var ch chan int
var rch <-chan int var rch <-chan int
var x int var x int
x <- x /* ERROR "cannot send" */ x <- /* ERROR "cannot send" */ x
rch <- x /* ERROR "cannot send" */ rch <- /* ERROR "cannot send" */ x
ch <- "foo" /* ERROR "cannot convert" */ ch <- "foo" /* ERROR "cannot convert" */
ch <- x ch <- x
} }
...@@ -381,7 +381,7 @@ func returns0() { ...@@ -381,7 +381,7 @@ func returns0() {
func returns1(x float64) (int, *float64) { func returns1(x float64) (int, *float64) {
return 0, &x return 0, &x
return /* ERROR wrong number of return values */ return /* ERROR wrong number of return values */
return "foo" /* ERROR "cannot convert" */, x /* ERROR "cannot return" */ return "foo" /* ERROR "cannot convert" */, x /* ERROR "cannot use .* in return statement" */
return /* ERROR wrong number of return values */ 0, &x, 1 return /* ERROR wrong number of return values */ 0, &x, 1
} }
...@@ -421,7 +421,7 @@ func switches0() { ...@@ -421,7 +421,7 @@ func switches0() {
true := "false" true := "false"
_ = true _ = true
// A tagless switch is equivalent to the bool // A tagless switch is equivalent to the bool
// constant true, not the identifier 'true'. // constant true, not the identifier 'true'.
switch { switch {
case "false" /* ERROR "cannot convert" */: case "false" /* ERROR "cannot convert" */:
...@@ -682,16 +682,16 @@ func typeswitches() { ...@@ -682,16 +682,16 @@ func typeswitches() {
switch t := x.(type) { switch t := x.(type) {
case nil: case nil:
var v bool = t /* ERROR "cannot initialize" */ var v bool = t /* ERROR "cannot use .* in variable declaration" */
_ = v _ = v
case int: case int:
var v int = t var v int = t
_ = v _ = v
case float32, complex64: case float32, complex64:
var v float32 = t /* ERROR "cannot initialize" */ var v float32 = t /* ERROR "cannot use .* in variable declaration" */
_ = v _ = v
default: default:
var v float32 = t /* ERROR "cannot initialize" */ var v float32 = t /* ERROR "cannot use .* in variable declaration" */
_ = v _ = v
} }
...@@ -801,7 +801,7 @@ func rangeloops1() { ...@@ -801,7 +801,7 @@ func rangeloops1() {
ii = i ii = i
_ = ii _ = ii
var xx float64 var xx float64
xx = x /* ERROR "cannot assign" */ xx = x /* ERROR "cannot use .* in assignment" */
_ = xx _ = xx
} }
var ii int var ii int
...@@ -852,7 +852,7 @@ func rangeloops1() { ...@@ -852,7 +852,7 @@ func rangeloops1() {
for range m {} for range m {}
for k := range m { for k := range m {
var kk int32 var kk int32
kk = k /* ERROR "cannot assign" */ kk = k /* ERROR "cannot use .* in assignment" */
_ = kk _ = kk
} }
for k, v := range m { for k, v := range m {
...@@ -894,17 +894,17 @@ func rangeloops2() { ...@@ -894,17 +894,17 @@ func rangeloops2() {
var a [10]int var a [10]int
var i I var i I
_ = i _ = i
for i /* ERROR cannot assign */ = range a {} for i /* ERROR cannot use .* in assignment */ = range a {}
for i /* ERROR cannot assign */ = range &a {} for i /* ERROR cannot use .* in assignment */ = range &a {}
for i /* ERROR cannot assign */ = range a[:] {} for i /* ERROR cannot use .* in assignment */ = range a[:] {}
var s string var s string
var r R var r R
_ = r _ = r
for i /* ERROR cannot assign */ = range s {} for i /* ERROR cannot use .* in assignment */ = range s {}
for i /* ERROR cannot assign */ = range "foo" {} for i /* ERROR cannot use .* in assignment */ = range "foo" {}
for _, r /* ERROR cannot assign */ = range s {} for _, r /* ERROR cannot use .* in assignment */ = range s {}
for _, r /* ERROR cannot assign */ = range "foo" {} for _, r /* ERROR cannot use .* in assignment */ = range "foo" {}
} }
func issue6766b() { func issue6766b() {
...@@ -937,7 +937,7 @@ func labels0() { ...@@ -937,7 +937,7 @@ func labels0() {
L1: L1:
L1 /* ERROR "already declared" */ : L1 /* ERROR "already declared" */ :
if true { if true {
goto L2 goto L2
L2: L2:
L0 /* ERROR "already declared" */ : L0 /* ERROR "already declared" */ :
} }
......
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