]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: pass *TypeName instead of *Named as def (defined) type
authorRobert Griesemer <gri@golang.org>
Thu, 31 Aug 2023 22:06:03 +0000 (15:06 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 20 Sep 2023 15:46:03 +0000 (15:46 +0000)
This permits using the same mechanism not just for *Named types but
also future Alias types.

Change-Id: Ia8dee413d8dff7b08ab073ce03a4779603c4f396
Reviewed-on: https://go-review.googlesource.com/c/go/+/524897
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>

src/cmd/compile/internal/types2/call.go
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/interface.go
src/cmd/compile/internal/types2/named.go
src/cmd/compile/internal/types2/typexpr.go
src/go/types/call.go
src/go/types/decl.go
src/go/types/interface.go
src/go/types/named.go
src/go/types/typexpr.go

index 718c54913d36bbe4c411376157e14ccde2661856..7b0fa10f32da1924eacda3d115975ac0a2ab1a5d 100644 (file)
@@ -658,7 +658,7 @@ var cgoPrefixes = [...]string{
        "_Cmacro_", // function to evaluate the expanded expression
 }
 
-func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named, wantType bool) {
+func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *TypeName, wantType bool) {
        // these must be declared before the "goto Error" statements
        var (
                obj      Object
@@ -759,8 +759,8 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named, w
        switch x.mode {
        case typexpr:
                // don't crash for "type T T.x" (was go.dev/issue/51509)
-               if def != nil && x.typ == def {
-                       check.cycleError([]Object{def.obj})
+               if def != nil && def.typ == x.typ {
+                       check.cycleError([]Object{def})
                        goto Error
                }
        case builtin:
index ccdfb19722843958378dbe7fa95fb7604a384949..ed6b96eb090aa2c790a00b1b851de3d913a5f90a 100644 (file)
@@ -55,7 +55,7 @@ func pathString(path []Object) string {
 
 // objDecl type-checks the declaration of obj in its respective (file) environment.
 // For the meaning of def, see Checker.definedType, in typexpr.go.
-func (check *Checker) objDecl(obj Object, def *Named) {
+func (check *Checker) objDecl(obj Object, def *TypeName) {
        if check.conf.Trace && obj.Type() == nil {
                if check.indent == 0 {
                        fmt.Println() // empty line between top-level objects for readability
@@ -483,7 +483,7 @@ func (check *Checker) isImportedConstraint(typ Type) bool {
        return u != nil && !u.IsMethodSet()
 }
 
-func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named) {
+func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *TypeName) {
        assert(obj.typ == nil)
 
        var rhs Type
@@ -514,7 +514,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
 
        // type definition or generic type declaration
        named := check.newNamed(obj, nil, nil)
-       def.setUnderlying(named)
+       setDefType(def, named)
 
        if tdecl.TParamList != nil {
                check.openScope(tdecl, "type parameters")
@@ -523,7 +523,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
        }
 
        // determine underlying type of named
-       rhs = check.definedType(tdecl.Type, named)
+       rhs = check.definedType(tdecl.Type, obj)
        assert(rhs != nil)
        named.fromRHS = rhs
 
index 3866975a91acb3982e644b40255cff77484285ae..a815ae2637bd78a4ca6cafa622db5335d4223ae7 100644 (file)
@@ -117,7 +117,7 @@ func (t *Interface) cleanup() {
        t.embedPos = nil
 }
 
-func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType, def *Named) {
+func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType, def *TypeName) {
        addEmbedded := func(pos syntax.Pos, typ Type) {
                ityp.embeddeds = append(ityp.embeddeds, typ)
                if ityp.embedPos == nil {
@@ -152,7 +152,9 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
                // use named receiver type if available (for better error messages)
                var recvTyp Type = ityp
                if def != nil {
-                       recvTyp = def
+                       if named, _ := def.typ.(*Named); named != nil {
+                               recvTyp = named
+                       }
                }
                sig.recv = NewVar(f.Name.Pos(), check.pkg, "", recvTyp)
 
index fbe7f8ed1249bc4ead021c69aad8b63a738958b0..81db4d84c19cac669610a023ffbb5af2cc724804 100644 (file)
@@ -550,12 +550,6 @@ loop:
        return u
 }
 
-func (n *Named) setUnderlying(typ Type) {
-       if n != nil {
-               n.underlying = typ
-       }
-}
-
 func (n *Named) lookupMethod(pkg *Package, name string, foldCase bool) (int, *Func) {
        n.resolve()
        // If n is an instance, we may not have yet instantiated all of its methods.
index 47e9dbae8b961dad5957b824fea6944164fdf2a5..b1a03bad3d7763453b6fbdc84b781575edc0f649 100644 (file)
@@ -18,7 +18,7 @@ import (
 // If an error occurred, x.mode is set to invalid.
 // For the meaning of def, see Checker.definedType, below.
 // If wantType is set, the identifier e is expected to denote a type.
-func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType bool) {
+func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType bool) {
        x.mode = invalid
        x.expr = e
 
@@ -173,10 +173,10 @@ func (check *Checker) validVarType(e syntax.Expr, typ Type) {
 }
 
 // definedType is like typ but also accepts a type name def.
-// If def != nil, e is the type specification for the defined type def, declared
-// in a type declaration, and def.underlying will be set to the type of e before
-// any components of e are type-checked.
-func (check *Checker) definedType(e syntax.Expr, def *Named) Type {
+// If def != nil, e is the type specification for the type named def, declared
+// in a type declaration, and def.typ.underlying will be set to the type of e
+// before any components of e are type-checked.
+func (check *Checker) definedType(e syntax.Expr, def *TypeName) Type {
        typ := check.typInternal(e, def)
        assert(isTyped(typ))
        if isGeneric(typ) {
@@ -212,7 +212,7 @@ func goTypeName(typ Type) string {
 
 // typInternal drives type checking of types.
 // Must only be called by definedType or genericType.
-func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
+func (check *Checker) typInternal(e0 syntax.Expr, def *TypeName) (T Type) {
        if check.conf.Trace {
                check.trace(e0.Pos(), "-- type %s", e0)
                check.indent++
@@ -243,7 +243,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
                switch x.mode {
                case typexpr:
                        typ := x.typ
-                       def.setUnderlying(typ)
+                       setDefType(def, typ)
                        return typ
                case invalid:
                        // ignore - error reported before
@@ -260,7 +260,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
                switch x.mode {
                case typexpr:
                        typ := x.typ
-                       def.setUnderlying(typ)
+                       setDefType(def, typ)
                        return typ
                case invalid:
                        // ignore - error reported before
@@ -281,7 +281,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
 
        case *syntax.ArrayType:
                typ := new(Array)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                if e.Len != nil {
                        typ.len = check.arrayLength(e.Len)
                } else {
@@ -297,7 +297,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
 
        case *syntax.SliceType:
                typ := new(Slice)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                typ.elem = check.varType(e.Elem)
                return typ
 
@@ -309,7 +309,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
 
        case *syntax.StructType:
                typ := new(Struct)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                check.structType(typ, e)
                return typ
 
@@ -317,7 +317,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
                if e.Op == syntax.Mul && e.Y == nil {
                        typ := new(Pointer)
                        typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
-                       def.setUnderlying(typ)
+                       setDefType(def, typ)
                        typ.base = check.varType(e.X)
                        // If typ.base is invalid, it's unlikely that *base is particularly
                        // useful - even a valid dereferenciation will lead to an invalid
@@ -334,19 +334,19 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
 
        case *syntax.FuncType:
                typ := new(Signature)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                check.funcType(typ, nil, nil, e)
                return typ
 
        case *syntax.InterfaceType:
                typ := check.newInterface()
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                check.interfaceType(typ, e, def)
                return typ
 
        case *syntax.MapType:
                typ := new(Map)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
 
                typ.key = check.varType(e.Key)
                typ.elem = check.varType(e.Value)
@@ -371,7 +371,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
 
        case *syntax.ChanType:
                typ := new(Chan)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
 
                dir := SendRecv
                switch e.Dir {
@@ -396,11 +396,25 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
        }
 
        typ := Typ[Invalid]
-       def.setUnderlying(typ)
+       setDefType(def, typ)
        return typ
 }
 
-func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *Named) (res Type) {
+func setDefType(def *TypeName, typ Type) {
+       if def != nil {
+               switch t := def.typ.(type) {
+               // case *_Alias:
+               case *Basic:
+                       assert(t == Typ[Invalid])
+               case *Named:
+                       t.underlying = typ
+               default:
+                       panic(fmt.Sprintf("unexpected type %T", t))
+               }
+       }
+}
+
+func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *TypeName) (res Type) {
        if check.conf.Trace {
                check.trace(x.Pos(), "-- instantiating type %s with %s", x, xlist)
                check.indent++
@@ -428,13 +442,13 @@ func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *
        // evaluate arguments
        targs := check.typeList(xlist)
        if targs == nil {
-               def.setUnderlying(Typ[Invalid]) // avoid errors later due to lazy instantiation
+               setDefType(def, Typ[Invalid]) // avoid errors later due to lazy instantiation
                return Typ[Invalid]
        }
 
        // create the instance
        inst := asNamed(check.instance(x.Pos(), orig, targs, nil, check.context()))
-       def.setUnderlying(inst)
+       setDefType(def, inst)
 
        // orig.tparams may not be set up, so we need to do expansion later.
        check.later(func() {
index f581a8ad51d6025c498d3306b40b7056902fac90..18c40629a57e765928d83107fe79cc119eca152a 100644 (file)
@@ -660,7 +660,7 @@ var cgoPrefixes = [...]string{
        "_Cmacro_", // function to evaluate the expanded expression
 }
 
-func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named, wantType bool) {
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *TypeName, wantType bool) {
        // these must be declared before the "goto Error" statements
        var (
                obj      Object
@@ -761,8 +761,8 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named, want
        switch x.mode {
        case typexpr:
                // don't crash for "type T T.x" (was go.dev/issue/51509)
-               if def != nil && x.typ == def {
-                       check.cycleError([]Object{def.obj})
+               if def != nil && def.typ == x.typ {
+                       check.cycleError([]Object{def})
                        goto Error
                }
        case builtin:
index d347ede219d39c630da996a620c28205095561cb..7d6a2aa039852c7e2c4b59e4a2c98775f3c72efe 100644 (file)
@@ -53,7 +53,7 @@ func pathString(path []Object) string {
 
 // objDecl type-checks the declaration of obj in its respective (file) environment.
 // For the meaning of def, see Checker.definedType, in typexpr.go.
-func (check *Checker) objDecl(obj Object, def *Named) {
+func (check *Checker) objDecl(obj Object, def *TypeName) {
        if check.conf._Trace && obj.Type() == nil {
                if check.indent == 0 {
                        fmt.Println() // empty line between top-level objects for readability
@@ -552,7 +552,7 @@ func (check *Checker) isImportedConstraint(typ Type) bool {
        return u != nil && !u.IsMethodSet()
 }
 
-func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
+func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *TypeName) {
        assert(obj.typ == nil)
 
        var rhs Type
@@ -583,7 +583,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
 
        // type definition or generic type declaration
        named := check.newNamed(obj, nil, nil)
-       def.setUnderlying(named)
+       setDefType(def, named)
 
        if tdecl.TypeParams != nil {
                check.openScope(tdecl, "type parameters")
@@ -592,7 +592,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
        }
 
        // determine underlying type of named
-       rhs = check.definedType(tdecl.Type, named)
+       rhs = check.definedType(tdecl.Type, obj)
        assert(rhs != nil)
        named.fromRHS = rhs
 
index 3aed723542debd54fd896adcf9f0cdddd687252d..0a258ce8672771ee5fd814d590d20ef307778377 100644 (file)
@@ -156,7 +156,7 @@ func (t *Interface) cleanup() {
        t.embedPos = nil
 }
 
-func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
+func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *TypeName) {
        addEmbedded := func(pos token.Pos, typ Type) {
                ityp.embeddeds = append(ityp.embeddeds, typ)
                if ityp.embedPos == nil {
@@ -200,7 +200,9 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
                // use named receiver type if available (for better error messages)
                var recvTyp Type = ityp
                if def != nil {
-                       recvTyp = def
+                       if named, _ := def.typ.(*Named); named != nil {
+                               recvTyp = named
+                       }
                }
                sig.recv = NewVar(name.Pos(), check.pkg, "", recvTyp)
 
index a27143b6c193e494d1d6e0ebcf2028828fa32833..440fc87891120f0d335a59e4579631f6a6bb818c 100644 (file)
@@ -552,12 +552,6 @@ loop:
        return u
 }
 
-func (n *Named) setUnderlying(typ Type) {
-       if n != nil {
-               n.underlying = typ
-       }
-}
-
 func (n *Named) lookupMethod(pkg *Package, name string, foldCase bool) (int, *Func) {
        n.resolve()
        // If n is an instance, we may not have yet instantiated all of its methods.
index 4c7c8a5ab5403299b1f32c665da447a9265c5cee..d35c6d1263798854135ad0e014291f91691e1e51 100644 (file)
@@ -19,7 +19,7 @@ import (
 // If an error occurred, x.mode is set to invalid.
 // For the meaning of def, see Checker.definedType, below.
 // If wantType is set, the identifier e is expected to denote a type.
-func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
+func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bool) {
        x.mode = invalid
        x.expr = e
 
@@ -173,10 +173,10 @@ func (check *Checker) validVarType(e ast.Expr, typ Type) {
 }
 
 // definedType is like typ but also accepts a type name def.
-// If def != nil, e is the type specification for the defined type def, declared
-// in a type declaration, and def.underlying will be set to the type of e before
-// any components of e are type-checked.
-func (check *Checker) definedType(e ast.Expr, def *Named) Type {
+// If def != nil, e is the type specification for the type named def, declared
+// in a type declaration, and def.typ.underlying will be set to the type of e
+// before any components of e are type-checked.
+func (check *Checker) definedType(e ast.Expr, def *TypeName) Type {
        typ := check.typInternal(e, def)
        assert(isTyped(typ))
        if isGeneric(typ) {
@@ -212,7 +212,7 @@ func goTypeName(typ Type) string {
 
 // typInternal drives type checking of types.
 // Must only be called by definedType or genericType.
-func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
+func (check *Checker) typInternal(e0 ast.Expr, def *TypeName) (T Type) {
        if check.conf._Trace {
                check.trace(e0.Pos(), "-- type %s", e0)
                check.indent++
@@ -243,7 +243,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
                switch x.mode {
                case typexpr:
                        typ := x.typ
-                       def.setUnderlying(typ)
+                       setDefType(def, typ)
                        return typ
                case invalid:
                        // ignore - error reported before
@@ -260,7 +260,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
                switch x.mode {
                case typexpr:
                        typ := x.typ
-                       def.setUnderlying(typ)
+                       setDefType(def, typ)
                        return typ
                case invalid:
                        // ignore - error reported before
@@ -283,13 +283,13 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
        case *ast.ArrayType:
                if e.Len == nil {
                        typ := new(Slice)
-                       def.setUnderlying(typ)
+                       setDefType(def, typ)
                        typ.elem = check.varType(e.Elt)
                        return typ
                }
 
                typ := new(Array)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                // Provide a more specific error when encountering a [...] array
                // rather than leaving it to the handling of the ... expression.
                if _, ok := e.Len.(*ast.Ellipsis); ok {
@@ -312,32 +312,32 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
 
        case *ast.StructType:
                typ := new(Struct)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                check.structType(typ, e)
                return typ
 
        case *ast.StarExpr:
                typ := new(Pointer)
                typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                typ.base = check.varType(e.X)
                return typ
 
        case *ast.FuncType:
                typ := new(Signature)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                check.funcType(typ, nil, e)
                return typ
 
        case *ast.InterfaceType:
                typ := check.newInterface()
-               def.setUnderlying(typ)
+               setDefType(def, typ)
                check.interfaceType(typ, e, def)
                return typ
 
        case *ast.MapType:
                typ := new(Map)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
 
                typ.key = check.varType(e.Key)
                typ.elem = check.varType(e.Value)
@@ -362,7 +362,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
 
        case *ast.ChanType:
                typ := new(Chan)
-               def.setUnderlying(typ)
+               setDefType(def, typ)
 
                dir := SendRecv
                switch e.Dir {
@@ -387,11 +387,25 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
        }
 
        typ := Typ[Invalid]
-       def.setUnderlying(typ)
+       setDefType(def, typ)
        return typ
 }
 
-func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (res Type) {
+func setDefType(def *TypeName, typ Type) {
+       if def != nil {
+               switch t := def.typ.(type) {
+               // case *_Alias:
+               case *Basic:
+                       assert(t == Typ[Invalid])
+               case *Named:
+                       t.underlying = typ
+               default:
+                       panic(fmt.Sprintf("unexpected type %T", t))
+               }
+       }
+}
+
+func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *TypeName) (res Type) {
        if check.conf._Trace {
                check.trace(ix.Pos(), "-- instantiating type %s with %s", ix.X, ix.Indices)
                check.indent++
@@ -419,13 +433,13 @@ func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (re
        // evaluate arguments
        targs := check.typeList(ix.Indices)
        if targs == nil {
-               def.setUnderlying(Typ[Invalid]) // avoid errors later due to lazy instantiation
+               setDefType(def, Typ[Invalid]) // avoid errors later due to lazy instantiation
                return Typ[Invalid]
        }
 
        // create the instance
        inst := asNamed(check.instance(ix.Pos(), orig, targs, nil, check.context()))
-       def.setUnderlying(inst)
+       setDefType(def, inst)
 
        // orig.tparams may not be set up, so we need to do expansion later.
        check.later(func() {