"_Cmacro_", // function to evaluate the expanded expression
}
-func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *TypeName, wantType bool) {
+func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool) {
// these must be declared before the "goto Error" statements
var (
obj Object
}
goto Error
}
- check.objDecl(exp, nil)
+ check.objDecl(exp)
} else {
exp = pkg.scope.Lookup(sel)
if exp == nil {
check.exprOrType(x, e.X, false)
switch x.mode {
- case typexpr:
- // don't crash for "type T T.x" (was go.dev/issue/51509)
- if def != nil && def.typ == x.typ {
- check.cycleError([]Object{def}, 0)
- goto Error
- }
case builtin:
check.errorf(e.Pos(), UncalledBuiltin, "invalid use of %s in selector expression", x)
goto Error
// methods may not have a fully set up signature yet
if m, _ := obj.(*Func); m != nil {
- check.objDecl(m, nil)
+ check.objDecl(m)
}
if x.mode == typexpr {
}
// 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 *TypeName) {
+func (check *Checker) objDecl(obj Object) {
if tracePos {
check.pushPos(obj.Pos())
defer func() {
check.varDecl(obj, d.lhs, d.vtyp, d.init)
case *TypeName:
// invalid recursive types are detected via path
- check.typeDecl(obj, d.tdecl, def)
+ check.typeDecl(obj, d.tdecl)
check.collectMethods(obj) // methods can only be added to top-level types
case *Func:
// functions may be recursive - no need to track dependencies
return u != nil && !u.IsMethodSet()
}
-func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *TypeName) {
+func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl) {
assert(obj.typ == nil)
// Only report a version error if we have not reported one already.
if check.conf.EnableAlias {
alias := check.newAlias(obj, nil)
- setDefType(def, alias)
// If we could not type the RHS, set it to invalid. This should
// only ever happen if we panic before setting.
}
named := check.newNamed(obj, nil, nil)
- setDefType(def, named)
// The RHS of a named N can be nil if, for example, N is defined as a cycle of aliases with
// gotypesalias=0. Consider:
scopePos := s.Name.Pos()
check.declare(check.scope, s.Name, obj, scopePos)
check.push(obj) // mark as grey
- check.typeDecl(obj, s, nil)
+ check.typeDecl(obj, s)
check.pop()
default:
goto Error // error was reported before
case *syntax.Name:
- check.ident(x, e, nil, false)
+ check.ident(x, e, false)
case *syntax.DotsType:
// dots are handled explicitly where they are valid
return kind
case *syntax.SelectorExpr:
- check.selector(x, e, nil, false)
+ check.selector(x, e, false)
case *syntax.IndexExpr:
if check.indexExpr(x, e) {
// methods may not have a fully set up signature yet
if check != nil {
- check.objDecl(f, nil)
+ check.objDecl(f)
}
if !equivalent(f.typ, m.typ) {
// This method may be formatted in funcString below, so must have a fully
// set up signature.
if check != nil {
- check.objDecl(f, nil)
+ check.objDecl(f)
}
}
switch state {
check := t.check
// Ensure that the original method is type-checked.
if check != nil {
- check.objDecl(origm, nil)
+ check.objDecl(origm)
}
origSig := origm.typ.(*Signature)
//
// Investigate and reenable this branch.
for _, obj := range check.objList {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
} else {
// Without Alias nodes, we process non-alias type declarations first, followed by
if check.objMap[tname].tdecl.Alias {
aliasList = append(aliasList, tname)
} else {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
} else {
othersList = append(othersList, obj)
}
// phase 2: alias type declarations
for _, obj := range aliasList {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
// phase 3: all other declarations
for _, obj := range othersList {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
}
// ident type-checks identifier e and initializes x with the value or type of e.
// If an error occurred, x.mode is set to invalid.
-// For the meaning of def, see Checker.declaredType, below.
// If wantType is set, the identifier e is expected to denote a type.
-func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType bool) {
+func (check *Checker) ident(x *operand, e *syntax.Name, wantType bool) {
x.mode = invalid
x.expr = e
// packages, to avoid races: see issue #69912.
typ := obj.Type()
if typ == nil || (gotType && wantType && obj.Pkg() == check.pkg) {
- check.objDecl(obj, def)
+ check.objDecl(obj)
typ = obj.Type() // type must have been assigned by Checker.objDecl
}
assert(typ != nil)
case *syntax.Name:
var x operand
- check.ident(&x, e, def, true)
+ check.ident(&x, e, true)
switch x.mode {
case typexpr:
- typ := x.typ
- setDefType(def, typ)
- return typ
+ return x.typ
case invalid:
// ignore - error reported before
case novalue:
case *syntax.SelectorExpr:
var x operand
- check.selector(&x, e, def, true)
+ check.selector(&x, e, true)
switch x.mode {
case typexpr:
- typ := x.typ
- setDefType(def, typ)
- return typ
+ return x.typ
case invalid:
// ignore - error reported before
case novalue:
case *syntax.IndexExpr:
check.verifyVersionf(e, go1_18, "type instantiation")
- return check.instantiatedType(e.X, syntax.UnpackListExpr(e.Index), def)
+ return check.instantiatedType(e.X, syntax.UnpackListExpr(e.Index))
case *syntax.ParenExpr:
// Generic types must be instantiated before they can be used in any form.
case *syntax.ArrayType:
typ := new(Array)
- setDefType(def, typ)
if e.Len != nil {
typ.len = check.arrayLength(e.Len)
} else {
case *syntax.SliceType:
typ := new(Slice)
- setDefType(def, typ)
typ.elem = check.varType(e.Elem)
return typ
case *syntax.StructType:
typ := new(Struct)
- setDefType(def, typ)
check.structType(typ, e)
return typ
if e.Op == syntax.Mul && e.Y == nil {
typ := new(Pointer)
typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
- 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
case *syntax.FuncType:
typ := new(Signature)
- setDefType(def, typ)
check.funcType(typ, nil, nil, e)
return typ
case *syntax.InterfaceType:
typ := check.newInterface()
- setDefType(def, typ)
check.interfaceType(typ, e, def)
return typ
case *syntax.MapType:
typ := new(Map)
- setDefType(def, typ)
-
typ.key = check.varType(e.Key)
typ.elem = check.varType(e.Value)
case *syntax.ChanType:
typ := new(Chan)
- setDefType(def, typ)
dir := SendRecv
switch e.Dir {
}
typ := Typ[Invalid]
- setDefType(def, typ)
return typ
}
-// TODO(markfreeman): Remove this function.
-func setDefType(def *TypeName, typ Type) {}
-
-func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *TypeName) (res Type) {
+func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr) (res Type) {
if check.conf.Trace {
check.trace(x.Pos(), "-- instantiating type %s with %s", x, xlist)
check.indent++
}()
}
- defer func() {
- setDefType(def, res)
- }()
-
var cause string
typ := check.genericType(x, &cause)
if cause != "" {
"_Cmacro_", // function to evaluate the expanded expression
}
-func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *TypeName, wantType bool) {
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
// these must be declared before the "goto Error" statements
var (
obj Object
}
goto Error
}
- check.objDecl(exp, nil)
+ check.objDecl(exp)
} else {
exp = pkg.scope.Lookup(sel)
if exp == nil {
check.exprOrType(x, e.X, false)
switch x.mode {
- case typexpr:
- // don't crash for "type T T.x" (was go.dev/issue/51509)
- if def != nil && def.typ == x.typ {
- check.cycleError([]Object{def}, 0)
- goto Error
- }
case builtin:
// types2 uses the position of '.' for the error
check.errorf(e.Sel, UncalledBuiltin, "invalid use of %s in selector expression", x)
// methods may not have a fully set up signature yet
if m, _ := obj.(*Func); m != nil {
- check.objDecl(m, nil)
+ check.objDecl(m)
}
if x.mode == typexpr {
}
// 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 *TypeName) {
+func (check *Checker) objDecl(obj Object) {
if tracePos {
check.pushPos(atPos(obj.Pos()))
defer func() {
check.varDecl(obj, d.lhs, d.vtyp, d.init)
case *TypeName:
// invalid recursive types are detected via path
- check.typeDecl(obj, d.tdecl, def)
+ check.typeDecl(obj, d.tdecl)
check.collectMethods(obj) // methods can only be added to top-level types
case *Func:
// functions may be recursive - no need to track dependencies
return u != nil && !u.IsMethodSet()
}
-func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *TypeName) {
+func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec) {
assert(obj.typ == nil)
// Only report a version error if we have not reported one already.
if check.conf._EnableAlias {
alias := check.newAlias(obj, nil)
- setDefType(def, alias)
// If we could not type the RHS, set it to invalid. This should
// only ever happen if we panic before setting.
}
named := check.newNamed(obj, nil, nil)
- setDefType(def, named)
// The RHS of a named N can be nil if, for example, N is defined as a cycle of aliases with
// gotypesalias=0. Consider:
scopePos := d.spec.Name.Pos()
check.declare(check.scope, d.spec.Name, obj, scopePos)
check.push(obj) // mark as grey
- check.typeDecl(obj, d.spec, nil)
+ check.typeDecl(obj, d.spec)
check.pop()
default:
check.errorf(d.node(), InvalidSyntaxTree, "unknown ast.Decl node %T", d.node())
goto Error // error was reported before
case *ast.Ident:
- check.ident(x, e, nil, false)
+ check.ident(x, e, false)
case *ast.Ellipsis:
// ellipses are handled explicitly where they are valid
return kind
case *ast.SelectorExpr:
- check.selector(x, e, nil, false)
+ check.selector(x, e, false)
case *ast.IndexExpr, *ast.IndexListExpr:
ix := unpackIndexedExpr(e)
// methods may not have a fully set up signature yet
if check != nil {
- check.objDecl(f, nil)
+ check.objDecl(f)
}
if !equivalent(f.typ, m.typ) {
// This method may be formatted in funcString below, so must have a fully
// set up signature.
if check != nil {
- check.objDecl(f, nil)
+ check.objDecl(f)
}
}
switch state {
check := t.check
// Ensure that the original method is type-checked.
if check != nil {
- check.objDecl(origm, nil)
+ check.objDecl(origm)
}
origSig := origm.typ.(*Signature)
//
// Investigate and reenable this branch.
for _, obj := range check.objList {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
} else {
// Without Alias nodes, we process non-alias type declarations first, followed by
if check.objMap[tname].tdecl.Assign.IsValid() {
aliasList = append(aliasList, tname)
} else {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
} else {
othersList = append(othersList, obj)
}
// phase 2: alias type declarations
for _, obj := range aliasList {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
// phase 3: all other declarations
for _, obj := range othersList {
- check.objDecl(obj, nil)
+ check.objDecl(obj)
}
}
// ident type-checks identifier e and initializes x with the value or type of e.
// If an error occurred, x.mode is set to invalid.
-// For the meaning of def, see Checker.declaredType, below.
// If wantType is set, the identifier e is expected to denote a type.
-func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bool) {
+func (check *Checker) ident(x *operand, e *ast.Ident, wantType bool) {
x.mode = invalid
x.expr = e
// packages, to avoid races: see issue #69912.
typ := obj.Type()
if typ == nil || (gotType && wantType && obj.Pkg() == check.pkg) {
- check.objDecl(obj, def)
+ check.objDecl(obj)
typ = obj.Type() // type must have been assigned by Checker.objDecl
}
assert(typ != nil)
case *ast.Ident:
var x operand
- check.ident(&x, e, def, true)
+ check.ident(&x, e, true)
switch x.mode {
case typexpr:
- typ := x.typ
- setDefType(def, typ)
- return typ
+ return x.typ
case invalid:
// ignore - error reported before
case novalue:
case *ast.SelectorExpr:
var x operand
- check.selector(&x, e, def, true)
+ check.selector(&x, e, true)
switch x.mode {
case typexpr:
- typ := x.typ
- setDefType(def, typ)
- return typ
+ return x.typ
case invalid:
// ignore - error reported before
case novalue:
case *ast.IndexExpr, *ast.IndexListExpr:
ix := unpackIndexedExpr(e)
check.verifyVersionf(inNode(e, ix.lbrack), go1_18, "type instantiation")
- return check.instantiatedType(ix, def)
+ return check.instantiatedType(ix)
case *ast.ParenExpr:
// Generic types must be instantiated before they can be used in any form.
case *ast.ArrayType:
if e.Len == nil {
typ := new(Slice)
- setDefType(def, typ)
typ.elem = check.varType(e.Elt)
return typ
}
typ := new(Array)
- 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 {
case *ast.StructType:
typ := new(Struct)
- 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
- 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
case *ast.FuncType:
typ := new(Signature)
- setDefType(def, typ)
check.funcType(typ, nil, e)
return typ
case *ast.InterfaceType:
typ := check.newInterface()
- setDefType(def, typ)
check.interfaceType(typ, e, def)
return typ
case *ast.MapType:
typ := new(Map)
- setDefType(def, typ)
-
typ.key = check.varType(e.Key)
typ.elem = check.varType(e.Value)
case *ast.ChanType:
typ := new(Chan)
- setDefType(def, typ)
dir := SendRecv
switch e.Dir {
}
typ := Typ[Invalid]
- setDefType(def, typ)
return typ
}
-// TODO(markfreeman): Remove this function.
-func setDefType(def *TypeName, typ Type) {}
-
-func (check *Checker) instantiatedType(ix *indexedExpr, def *TypeName) (res Type) {
+func (check *Checker) instantiatedType(ix *indexedExpr) (res Type) {
if check.conf._Trace {
check.trace(ix.Pos(), "-- instantiating type %s with %s", ix.x, ix.indices)
check.indent++
}()
}
- defer func() {
- setDefType(def, res)
- }()
-
var cause string
typ := check.genericType(ix.x, &cause)
if cause != "" {