mirror of
https://github.com/golang/go
synced 2024-09-29 22:24:33 -06:00
cmd/compile/internal/types2: remove most asX converters (cleanup)
Make it explicit in the code where we call under. The asNamed and asTypeParam converters need to stay: asNamed does resolution if necessary, and asTypeParam may or may not call under() depending on the next CL. Reviewed uses of asNamed and .(*Named) for correctness. Removed unnecessary Named.resolve call in lookup. Change-Id: I2acf176925e00bd1703a00230a779aa65a8f5a51 Reviewed-on: https://go-review.googlesource.com/c/go/+/362254 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
3e41b18a46
commit
759eaa22ad
@ -71,7 +71,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
|
||||
// x.typ is typed
|
||||
|
||||
// A generic (non-instantiated) function value cannot be assigned to a variable.
|
||||
if sig := asSignature(x.typ); sig != nil && sig.TypeParams().Len() > 0 {
|
||||
if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
|
||||
check.errorf(x, "cannot use generic function %s without instantiation in %s", x, context)
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
||||
// (applyTypeFunc never calls f with a type parameter)
|
||||
f := func(typ Type) Type {
|
||||
assert(asTypeParam(typ) == nil)
|
||||
if t := asBasic(typ); t != nil {
|
||||
if t, _ := under(typ).(*Basic); t != nil {
|
||||
switch t.kind {
|
||||
case Float32:
|
||||
return Typ[Complex64]
|
||||
@ -418,7 +418,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
||||
// (applyTypeFunc never calls f with a type parameter)
|
||||
f := func(typ Type) Type {
|
||||
assert(asTypeParam(typ) == nil)
|
||||
if t := asBasic(typ); t != nil {
|
||||
if t, _ := under(typ).(*Basic); t != nil {
|
||||
switch t.kind {
|
||||
case Complex64:
|
||||
return Typ[Float32]
|
||||
@ -704,7 +704,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
|
||||
return
|
||||
}
|
||||
|
||||
typ := asPointer(x.typ)
|
||||
typ, _ := under(x.typ).(*Pointer)
|
||||
if typ == nil {
|
||||
check.errorf(x, invalidArg+"%s is not a pointer", x)
|
||||
return
|
||||
@ -894,7 +894,7 @@ func makeSig(res Type, args ...Type) *Signature {
|
||||
// otherwise it returns typ.
|
||||
func arrayPtrDeref(typ Type) Type {
|
||||
if p, ok := typ.(*Pointer); ok {
|
||||
if a := asArray(p.base); a != nil {
|
||||
if a, _ := under(p.base).(*Array); a != nil {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
|
||||
case 1:
|
||||
check.expr(x, call.ArgList[0])
|
||||
if x.mode != invalid {
|
||||
if t := asInterface(T); t != nil {
|
||||
if t, _ := under(T).(*Interface); t != nil {
|
||||
if !t.IsMethodSet() {
|
||||
check.errorf(call, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
|
||||
break
|
||||
|
@ -39,7 +39,7 @@ func (ctxt *Context) TypeHash(typ Type, targs []Type) string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
h := newTypeHasher(&buf, ctxt)
|
||||
if named, _ := typ.(*Named); named != nil && len(targs) > 0 {
|
||||
if named := asNamed(typ); named != nil && len(targs) > 0 {
|
||||
// Don't use WriteType because we need to use the provided targs
|
||||
// and not any targs that might already be with the *Named type.
|
||||
h.typePrefix(named)
|
||||
|
@ -18,7 +18,7 @@ func (check *Checker) conversion(x *operand, T Type) {
|
||||
constArg := x.mode == constant_
|
||||
|
||||
constConvertibleTo := func(T Type, val *constant.Value) bool {
|
||||
switch t := asBasic(T); {
|
||||
switch t, _ := under(T).(*Basic); {
|
||||
case t == nil:
|
||||
// nothing to do
|
||||
case representableConst(x.val, check, t, val):
|
||||
@ -173,9 +173,9 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
|
||||
|
||||
// "V a slice, T is a pointer-to-array type,
|
||||
// and the slice and array types have identical element types."
|
||||
if s := asSlice(V); s != nil {
|
||||
if p := asPointer(T); p != nil {
|
||||
if a := asArray(p.Elem()); a != nil {
|
||||
if s, _ := under(V).(*Slice); s != nil {
|
||||
if p, _ := under(T).(*Pointer); p != nil {
|
||||
if a, _ := under(p.Elem()).(*Array); a != nil {
|
||||
if Identical(s.Elem(), a.Elem()) {
|
||||
if check == nil || check.allowVersion(check.pkg, 1, 17) {
|
||||
return true
|
||||
@ -262,26 +262,27 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
|
||||
// use the toT convenience converters in the predicates below.
|
||||
|
||||
func isUintptr(typ Type) bool {
|
||||
t := asBasic(typ)
|
||||
t, _ := under(typ).(*Basic)
|
||||
return t != nil && t.kind == Uintptr
|
||||
}
|
||||
|
||||
func isUnsafePointer(typ Type) bool {
|
||||
// TODO(gri): Is this asBasic(typ) instead of typ.(*Basic) correct?
|
||||
// TODO(gri): Is this under(typ).(*Basic) instead of typ.(*Basic) correct?
|
||||
// (The former calls under(), while the latter doesn't.)
|
||||
// The spec does not say so, but gc claims it is. See also
|
||||
// issue 6326.
|
||||
t := asBasic(typ)
|
||||
t, _ := under(typ).(*Basic)
|
||||
return t != nil && t.kind == UnsafePointer
|
||||
}
|
||||
|
||||
func isPointer(typ Type) bool {
|
||||
return asPointer(typ) != nil
|
||||
_, ok := under(typ).(*Pointer)
|
||||
return ok
|
||||
}
|
||||
|
||||
func isBytesOrRunes(typ Type) bool {
|
||||
if s := asSlice(typ); s != nil {
|
||||
t := asBasic(s.elem)
|
||||
if s, _ := under(typ).(*Slice); s != nil {
|
||||
t, _ := under(s.elem).(*Basic)
|
||||
return t != nil && (t.kind == Byte || t.kind == Rune)
|
||||
}
|
||||
return false
|
||||
|
@ -116,7 +116,7 @@ func (check *Checker) overflow(x *operand) {
|
||||
// x.typ cannot be a type parameter (type
|
||||
// parameters cannot be constant types).
|
||||
if isTyped(x.typ) {
|
||||
check.representable(x, asBasic(x.typ))
|
||||
check.representable(x, under(x.typ).(*Basic))
|
||||
return
|
||||
}
|
||||
|
||||
@ -617,7 +617,7 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
|
||||
// If the new type is not final and still untyped, just
|
||||
// update the recorded type.
|
||||
if !final && isUntyped(typ) {
|
||||
old.typ = asBasic(typ)
|
||||
old.typ = under(typ).(*Basic)
|
||||
check.untyped[x] = old
|
||||
return
|
||||
}
|
||||
@ -1394,7 +1394,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
|
||||
duplicate := false
|
||||
// if the key is of interface type, the type is also significant when checking for duplicates
|
||||
xkey := keyVal(x.val)
|
||||
if asInterface(utyp.key) != nil {
|
||||
if IsInterface(utyp.key) {
|
||||
for _, vtyp := range visited[xkey] {
|
||||
if Identical(vtyp, x.typ) {
|
||||
duplicate = true
|
||||
|
@ -34,7 +34,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
|
||||
return false
|
||||
|
||||
case value:
|
||||
if sig := asSignature(x.typ); sig != nil && sig.TypeParams().Len() > 0 {
|
||||
if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
|
||||
// function instantiation
|
||||
return true
|
||||
}
|
||||
@ -72,7 +72,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
|
||||
x.typ = typ.elem
|
||||
|
||||
case *Pointer:
|
||||
if typ := asArray(typ.base); typ != nil {
|
||||
if typ, _ := under(typ.base).(*Array); typ != nil {
|
||||
valid = true
|
||||
length = typ.len
|
||||
x.mode = variable
|
||||
@ -120,7 +120,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
|
||||
mode = value
|
||||
}
|
||||
case *Pointer:
|
||||
if t := asArray(t.base); t != nil {
|
||||
if t, _ := under(t.base).(*Array); t != nil {
|
||||
l = t.len
|
||||
e = t.elem
|
||||
}
|
||||
@ -245,7 +245,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
|
||||
x.typ = &Slice{elem: u.elem}
|
||||
|
||||
case *Pointer:
|
||||
if u := asArray(u.base); u != nil {
|
||||
if u, _ := under(u.base).(*Array); u != nil {
|
||||
valid = true
|
||||
length = u.len
|
||||
x.typ = &Slice{elem: u.elem}
|
||||
|
@ -122,7 +122,6 @@ func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
|
||||
seen[named] = true
|
||||
|
||||
// look for a matching attached method
|
||||
named.resolve(nil)
|
||||
if i, m := lookupMethod(named.methods, pkg, name); m != nil {
|
||||
// potential match
|
||||
// caution: method may not have a proper signature yet
|
||||
@ -306,7 +305,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
|
||||
return
|
||||
}
|
||||
|
||||
if ityp := asInterface(V); ityp != nil {
|
||||
if ityp, _ := under(V).(*Interface); ityp != nil {
|
||||
// TODO(gri) the methods are sorted - could do this more efficiently
|
||||
for _, m := range T.typeSet().methods {
|
||||
_, f := ityp.typeSet().LookupMethod(m.pkg, m.name)
|
||||
@ -417,7 +416,7 @@ func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Fun
|
||||
// no static check is required if T is an interface
|
||||
// spec: "If T is an interface type, x.(T) asserts that the
|
||||
// dynamic type of x implements the interface T."
|
||||
if asInterface(T) != nil && !forceStrict {
|
||||
if IsInterface(T) && !forceStrict {
|
||||
return
|
||||
}
|
||||
return check.missingMethod(T, V, false)
|
||||
@ -435,8 +434,8 @@ func deref(typ Type) (Type, bool) {
|
||||
// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
|
||||
// (named or unnamed) struct and returns its base. Otherwise it returns typ.
|
||||
func derefStructPtr(typ Type) Type {
|
||||
if p := asPointer(typ); p != nil {
|
||||
if asStruct(p.base) != nil {
|
||||
if p, _ := under(typ).(*Pointer); p != nil {
|
||||
if _, ok := under(p.base).(*Struct); ok {
|
||||
return p.base
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func hasName(t Type) bool {
|
||||
// are not fully set up.
|
||||
func isTyped(t Type) bool {
|
||||
// isTyped is called with types that are not fully
|
||||
// set up. Must not call asBasic()!
|
||||
// set up. Must not call under()!
|
||||
b, _ := t.(*Basic)
|
||||
return b == nil || b.info&IsUntyped == 0
|
||||
}
|
||||
@ -84,7 +84,8 @@ func isUntyped(t Type) bool {
|
||||
|
||||
// IsInterface reports whether t is an interface type.
|
||||
func IsInterface(t Type) bool {
|
||||
return asInterface(t) != nil
|
||||
_, ok := under(t).(*Interface)
|
||||
return ok
|
||||
}
|
||||
|
||||
// isTypeParam reports whether t is a type parameter.
|
||||
|
@ -243,7 +243,7 @@ func (conf *Config) offsetsof(T *Struct) []int64 {
|
||||
func (conf *Config) offsetof(typ Type, index []int) int64 {
|
||||
var o int64
|
||||
for _, i := range index {
|
||||
s := asStruct(typ)
|
||||
s := under(typ).(*Struct)
|
||||
o += conf.offsetsof(s)[i]
|
||||
typ = s.fields[i].typ
|
||||
}
|
||||
|
@ -27,45 +27,8 @@ func under(t Type) Type {
|
||||
return t
|
||||
}
|
||||
|
||||
// Convenience converters
|
||||
|
||||
func asBasic(t Type) *Basic {
|
||||
u, _ := under(t).(*Basic)
|
||||
return u
|
||||
}
|
||||
|
||||
func asArray(t Type) *Array {
|
||||
u, _ := under(t).(*Array)
|
||||
return u
|
||||
}
|
||||
|
||||
func asSlice(t Type) *Slice {
|
||||
u, _ := under(t).(*Slice)
|
||||
return u
|
||||
}
|
||||
|
||||
func asStruct(t Type) *Struct {
|
||||
u, _ := under(t).(*Struct)
|
||||
return u
|
||||
}
|
||||
|
||||
func asPointer(t Type) *Pointer {
|
||||
u, _ := under(t).(*Pointer)
|
||||
return u
|
||||
}
|
||||
|
||||
func asSignature(t Type) *Signature {
|
||||
u, _ := under(t).(*Signature)
|
||||
return u
|
||||
}
|
||||
|
||||
func asInterface(t Type) *Interface {
|
||||
u, _ := under(t).(*Interface)
|
||||
return u
|
||||
}
|
||||
|
||||
// If the argument to asNamed, or asTypeParam is of the respective type
|
||||
// (possibly after expanding resolving a *Named type), these methods return that type.
|
||||
// (possibly after resolving a *Named type), these methods return that type.
|
||||
// Otherwise the result is nil.
|
||||
|
||||
func asNamed(t Type) *Named {
|
||||
|
@ -361,7 +361,7 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
|
||||
} else {
|
||||
// special case:
|
||||
// append(s, "foo"...) leads to signature func([]byte, string...)
|
||||
if t := asBasic(typ); t == nil || t.kind != String {
|
||||
if t, _ := under(typ).(*Basic); t == nil || t.kind != String {
|
||||
w.error("expected string type")
|
||||
continue
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ func (check *Checker) varType(e syntax.Expr) Type {
|
||||
// are in the middle of type-checking parameter declarations that might belong to
|
||||
// interface methods. Delay this check to the end of type-checking.
|
||||
check.later(func() {
|
||||
if t := asInterface(typ); t != nil {
|
||||
if t, _ := under(typ).(*Interface); t != nil {
|
||||
pos := syntax.StartPos(e)
|
||||
tset := computeInterfaceTypeSet(check, pos, t) // TODO(gri) is this the correct position?
|
||||
if !tset.IsMethodSet() {
|
||||
|
Loading…
Reference in New Issue
Block a user