-// UNREVIEWED
// Copyright 2013 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.
case *syntax.ListExpr:
var elems []syntax.Expr
for i, elem := range n.ElemList {
- Elem := isubst(elem, smap)
- if Elem != elem {
+ new := isubst(elem, smap)
+ if new != elem {
if elems == nil {
elems = make([]syntax.Expr, len(n.ElemList))
copy(elems, n.ElemList)
}
- elems[i] = Elem
+ elems[i] = new
}
}
if elems != nil {
for i, t := range sig.rparams {
list[i] = t.typ
}
+ smap := makeSubstMap(recvTParams, list)
for i, tname := range sig.rparams {
bound := recvTParams[i].typ.(*TypeParam).bound
// bound is (possibly) parameterized in the context of the
// TODO(gri) should we assume now that bounds always exist?
// (no bound == empty interface)
if bound != nil {
- bound = check.subst(tname.pos, bound, makeSubstMap(recvTParams, list))
+ bound = check.subst(tname.pos, bound, smap)
tname.typ.(*TypeParam).bound = bound
}
}
unreachable() // should have been caught by genericType
}
- // create a new type Instance rather than instantiate the type
+ // create a new type instance rather than instantiate the type
// TODO(gri) should do argument number check here rather than
- // when instantiating the type?
+ // when instantiating the type?
typ := new(instance)
def.setUnderlying(typ)
add(f.Name, false, f.Name.Pos())
} else {
// embedded field
- // spec: "An embedded type must be specified as a (possibly parenthesized) type name T or
- // as a pointer to a non-interface type name *T, and T itself may not be a pointer type."
+ // spec: "An embedded type must be specified as a type name T or as a
+ // pointer to a non-interface type name *T, and T itself may not be a
+ // pointer type."
pos := startPos(f.Type)
name := embeddedFieldIdent(f.Type)
if name == nil {
continue
}
add(name, true, pos)
+
// Because we have a name, typ must be of the form T or *T, where T is the name
// of a (named or alias) type, and t (= deref(typ)) must be the type of T.
// We must delay this check to the end because we don't want to instantiate
list = append(list, typ)
}
- // Ensure that each type is only present once in the type list.
- // Types may be interfaces, which may not be complete yet. It's
- // ok to do this check at the end because it's not a requirement
- // for correctness of the code.
+ // Ensure that each type is only present once in the type list. Types may be
+ // interfaces, which may not be complete yet. It's ok to do this check at the
+ // end because it's not a requirement for correctness of the code.
+ // Note: This is a quadratic algorithm, but type lists tend to be short.
check.atEnd(func() {
- uniques := make([]Type, 0, len(list)) // assume all types are unique
for i, t := range list {
if t := t.Interface(); t != nil {
check.completeInterface(types[i].Pos(), t)
}
- if includes(uniques, t) {
+ if includes(list[:i], t) {
check.softErrorf(types[i], "duplicate type %s in type list", t)
}
- uniques = append(uniques, t)
}
})