n.Orig = norig
}
-// checkMapKeyType checks that Type key is valid for use as a map key.
-func checkMapKeyType(key *Type) {
- alg, bad := algtype1(key)
- if alg != ANOEQ {
- return
- }
- switch bad.Etype {
- default:
- Yyerror("invalid map key type %v", key)
- case TANY:
- // Will be resolved later.
- case TFORW:
- // map[key] used during definition of key.
- // postpone check until key is fully defined.
- // if there are multiple uses of map[key]
- // before key is fully defined, the error
- // will only be printed for the first one.
- // good enough.
- if maplineno[key] == 0 {
- maplineno[key] = lineno
- }
- }
-}
-
// methcmp sorts by symbol, then by package path for unexported symbols.
type methcmp []*Field
}
n.Op = OTYPE
n.Type = typMap(l.Type, r.Type)
+
+ // map key validation
+ alg, bad := algtype1(l.Type)
+ if alg == ANOEQ {
+ if bad.Etype == TFORW {
+ // queue check for map until all the types are done settling.
+ mapqueue = append(mapqueue, mapqueueval{l, n.Lineno})
+ } else if bad.Etype != TANY {
+ // no need to queue, key is already bad
+ Yyerror("invalid map key type %v", l.Type)
+ }
+ }
n.Left = nil
n.Right = nil
checkwidth(n.Type)
}
-var (
- mapqueue []*Node
- // maplineno tracks the line numbers at which types are first used as map keys
- maplineno = map[*Type]int32{}
-)
+type mapqueueval struct {
+ n *Node
+ lno int32
+}
+
+// tracks the line numbers at which forward types are first used as map keys
+var mapqueue []mapqueueval
func copytype(n *Node, t *Type) {
if t.Etype == TFORW {
return
}
- mapline := maplineno[n.Type]
embedlineno := n.Type.ForwardType().Embedlineno
l := n.Type.ForwardType().Copyto
}
lineno = lno
-
- // Queue check for map until all the types are done settling.
- if mapline != 0 {
- maplineno[t] = mapline
- mapqueue = append(mapqueue, n)
- }
}
func typecheckdeftype(n *Node) {
domethod(n)
}
}
-
- for _, n := range mapqueue {
- lineno = maplineno[n.Type]
- checkMapKeyType(n.Type)
+ for _, e := range mapqueue {
+ lineno = e.lno
+ if !e.n.Type.IsComparable() {
+ Yyerror("invalid map key type %v", e.n.Type)
+ }
}
-
+ mapqueue = nil
lineno = lno
}
--- /dev/null
+// errorcheck
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 14988: defining a map with an invalid forward declaration array
+// key doesn't cause a fatal.
+
+package main
+
+type m map[k]int // ERROR "invalid map key type"
+type k [1]m