Source file src/cmd/compile/internal/types2/typexpr.go

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file implements type-checking of identifiers and type expressions.
     6  
     7  package types2
     8  
     9  import (
    10  	"cmd/compile/internal/syntax"
    11  	"fmt"
    12  	"go/constant"
    13  	. "internal/types/errors"
    14  	"strings"
    15  )
    16  
    17  // ident type-checks identifier e and initializes x with the value or type of e.
    18  // If an error occurred, x.mode is set to invalid.
    19  // For the meaning of def, see Checker.definedType, below.
    20  // If wantType is set, the identifier e is expected to denote a type.
    21  func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType bool) {
    22  	x.mode = invalid
    23  	x.expr = e
    24  
    25  	// Note that we cannot use check.lookup here because the returned scope
    26  	// may be different from obj.Parent(). See also Scope.LookupParent doc.
    27  	scope, obj := check.scope.LookupParent(e.Value, check.pos)
    28  	switch obj {
    29  	case nil:
    30  		if e.Value == "_" {
    31  			// Blank identifiers are never declared, but the current identifier may
    32  			// be a placeholder for a receiver type parameter. In this case we can
    33  			// resolve its type and object from Checker.recvTParamMap.
    34  			if tpar := check.recvTParamMap[e]; tpar != nil {
    35  				x.mode = typexpr
    36  				x.typ = tpar
    37  			} else {
    38  				check.error(e, InvalidBlank, "cannot use _ as value or type")
    39  			}
    40  		} else {
    41  			check.errorf(e, UndeclaredName, "undefined: %s", e.Value)
    42  		}
    43  		return
    44  	case universeAny, universeComparable:
    45  		if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Value) {
    46  			return // avoid follow-on errors
    47  		}
    48  	}
    49  	check.recordUse(e, obj)
    50  
    51  	// Type-check the object.
    52  	// Only call Checker.objDecl if the object doesn't have a type yet
    53  	// (in which case we must actually determine it) or the object is a
    54  	// TypeName and we also want a type (in which case we might detect
    55  	// a cycle which needs to be reported). Otherwise we can skip the
    56  	// call and avoid a possible cycle error in favor of the more
    57  	// informative "not a type/value" error that this function's caller
    58  	// will issue (see go.dev/issue/25790).
    59  	typ := obj.Type()
    60  	if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
    61  		check.objDecl(obj, def)
    62  		typ = obj.Type() // type must have been assigned by Checker.objDecl
    63  	}
    64  	assert(typ != nil)
    65  
    66  	// The object may have been dot-imported.
    67  	// If so, mark the respective package as used.
    68  	// (This code is only needed for dot-imports. Without them,
    69  	// we only have to mark variables, see *Var case below).
    70  	if pkgName := check.dotImportMap[dotImportKey{scope, obj.Name()}]; pkgName != nil {
    71  		pkgName.used = true
    72  	}
    73  
    74  	switch obj := obj.(type) {
    75  	case *PkgName:
    76  		check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
    77  		return
    78  
    79  	case *Const:
    80  		check.addDeclDep(obj)
    81  		if !isValid(typ) {
    82  			return
    83  		}
    84  		if obj == universeIota {
    85  			if check.iota == nil {
    86  				check.error(e, InvalidIota, "cannot use iota outside constant declaration")
    87  				return
    88  			}
    89  			x.val = check.iota
    90  		} else {
    91  			x.val = obj.val
    92  		}
    93  		assert(x.val != nil)
    94  		x.mode = constant_
    95  
    96  	case *TypeName:
    97  		if !check.enableAlias && check.isBrokenAlias(obj) {
    98  			check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name)
    99  			return
   100  		}
   101  		x.mode = typexpr
   102  
   103  	case *Var:
   104  		// It's ok to mark non-local variables, but ignore variables
   105  		// from other packages to avoid potential race conditions with
   106  		// dot-imported variables.
   107  		if obj.pkg == check.pkg {
   108  			obj.used = true
   109  		}
   110  		check.addDeclDep(obj)
   111  		if !isValid(typ) {
   112  			return
   113  		}
   114  		x.mode = variable
   115  
   116  	case *Func:
   117  		check.addDeclDep(obj)
   118  		x.mode = value
   119  
   120  	case *Builtin:
   121  		x.id = obj.id
   122  		x.mode = builtin
   123  
   124  	case *Nil:
   125  		x.mode = nilvalue
   126  
   127  	default:
   128  		unreachable()
   129  	}
   130  
   131  	x.typ = typ
   132  }
   133  
   134  // typ type-checks the type expression e and returns its type, or Typ[Invalid].
   135  // The type must not be an (uninstantiated) generic type.
   136  func (check *Checker) typ(e syntax.Expr) Type {
   137  	return check.definedType(e, nil)
   138  }
   139  
   140  // varType type-checks the type expression e and returns its type, or Typ[Invalid].
   141  // The type must not be an (uninstantiated) generic type and it must not be a
   142  // constraint interface.
   143  func (check *Checker) varType(e syntax.Expr) Type {
   144  	typ := check.definedType(e, nil)
   145  	check.validVarType(e, typ)
   146  	return typ
   147  }
   148  
   149  // validVarType reports an error if typ is a constraint interface.
   150  // The expression e is used for error reporting, if any.
   151  func (check *Checker) validVarType(e syntax.Expr, typ Type) {
   152  	// If we have a type parameter there's nothing to do.
   153  	if isTypeParam(typ) {
   154  		return
   155  	}
   156  
   157  	// We don't want to call under() or complete interfaces while we are in
   158  	// the middle of type-checking parameter declarations that might belong
   159  	// to interface methods. Delay this check to the end of type-checking.
   160  	check.later(func() {
   161  		if t, _ := under(typ).(*Interface); t != nil {
   162  			pos := syntax.StartPos(e)
   163  			tset := computeInterfaceTypeSet(check, pos, t) // TODO(gri) is this the correct position?
   164  			if !tset.IsMethodSet() {
   165  				if tset.comparable {
   166  					check.softErrorf(pos, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
   167  				} else {
   168  					check.softErrorf(pos, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
   169  				}
   170  			}
   171  		}
   172  	}).describef(e, "check var type %s", typ)
   173  }
   174  
   175  // definedType is like typ but also accepts a type name def.
   176  // If def != nil, e is the type specification for the type named def, declared
   177  // in a type declaration, and def.typ.underlying will be set to the type of e
   178  // before any components of e are type-checked.
   179  func (check *Checker) definedType(e syntax.Expr, def *TypeName) Type {
   180  	typ := check.typInternal(e, def)
   181  	assert(isTyped(typ))
   182  	if isGeneric(typ) {
   183  		check.errorf(e, WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
   184  		typ = Typ[Invalid]
   185  	}
   186  	check.recordTypeAndValue(e, typexpr, typ, nil)
   187  	return typ
   188  }
   189  
   190  // genericType is like typ but the type must be an (uninstantiated) generic
   191  // type. If cause is non-nil and the type expression was a valid type but not
   192  // generic, cause will be populated with a message describing the error.
   193  func (check *Checker) genericType(e syntax.Expr, cause *string) Type {
   194  	typ := check.typInternal(e, nil)
   195  	assert(isTyped(typ))
   196  	if isValid(typ) && !isGeneric(typ) {
   197  		if cause != nil {
   198  			*cause = check.sprintf("%s is not a generic type", typ)
   199  		}
   200  		typ = Typ[Invalid]
   201  	}
   202  	// TODO(gri) what is the correct call below?
   203  	check.recordTypeAndValue(e, typexpr, typ, nil)
   204  	return typ
   205  }
   206  
   207  // goTypeName returns the Go type name for typ and
   208  // removes any occurrences of "types2." from that name.
   209  func goTypeName(typ Type) string {
   210  	return strings.ReplaceAll(fmt.Sprintf("%T", typ), "types2.", "")
   211  }
   212  
   213  // typInternal drives type checking of types.
   214  // Must only be called by definedType or genericType.
   215  func (check *Checker) typInternal(e0 syntax.Expr, def *TypeName) (T Type) {
   216  	if check.conf.Trace {
   217  		check.trace(e0.Pos(), "-- type %s", e0)
   218  		check.indent++
   219  		defer func() {
   220  			check.indent--
   221  			var under Type
   222  			if T != nil {
   223  				// Calling under() here may lead to endless instantiations.
   224  				// Test case: type T[P any] *T[P]
   225  				under = safeUnderlying(T)
   226  			}
   227  			if T == under {
   228  				check.trace(e0.Pos(), "=> %s // %s", T, goTypeName(T))
   229  			} else {
   230  				check.trace(e0.Pos(), "=> %s (under = %s) // %s", T, under, goTypeName(T))
   231  			}
   232  		}()
   233  	}
   234  
   235  	switch e := e0.(type) {
   236  	case *syntax.BadExpr:
   237  		// ignore - error reported before
   238  
   239  	case *syntax.Name:
   240  		var x operand
   241  		check.ident(&x, e, def, true)
   242  
   243  		switch x.mode {
   244  		case typexpr:
   245  			typ := x.typ
   246  			setDefType(def, typ)
   247  			return typ
   248  		case invalid:
   249  			// ignore - error reported before
   250  		case novalue:
   251  			check.errorf(&x, NotAType, "%s used as type", &x)
   252  		default:
   253  			check.errorf(&x, NotAType, "%s is not a type", &x)
   254  		}
   255  
   256  	case *syntax.SelectorExpr:
   257  		var x operand
   258  		check.selector(&x, e, def, true)
   259  
   260  		switch x.mode {
   261  		case typexpr:
   262  			typ := x.typ
   263  			setDefType(def, typ)
   264  			return typ
   265  		case invalid:
   266  			// ignore - error reported before
   267  		case novalue:
   268  			check.errorf(&x, NotAType, "%s used as type", &x)
   269  		default:
   270  			check.errorf(&x, NotAType, "%s is not a type", &x)
   271  		}
   272  
   273  	case *syntax.IndexExpr:
   274  		check.verifyVersionf(e, go1_18, "type instantiation")
   275  		return check.instantiatedType(e.X, syntax.UnpackListExpr(e.Index), def)
   276  
   277  	case *syntax.ParenExpr:
   278  		// Generic types must be instantiated before they can be used in any form.
   279  		// Consequently, generic types cannot be parenthesized.
   280  		return check.definedType(e.X, def)
   281  
   282  	case *syntax.ArrayType:
   283  		typ := new(Array)
   284  		setDefType(def, typ)
   285  		if e.Len != nil {
   286  			typ.len = check.arrayLength(e.Len)
   287  		} else {
   288  			// [...]array
   289  			check.error(e, BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
   290  			typ.len = -1
   291  		}
   292  		typ.elem = check.varType(e.Elem)
   293  		if typ.len >= 0 {
   294  			return typ
   295  		}
   296  		// report error if we encountered [...]
   297  
   298  	case *syntax.SliceType:
   299  		typ := new(Slice)
   300  		setDefType(def, typ)
   301  		typ.elem = check.varType(e.Elem)
   302  		return typ
   303  
   304  	case *syntax.DotsType:
   305  		// dots are handled explicitly where they are legal
   306  		// (array composite literals and parameter lists)
   307  		check.error(e, InvalidDotDotDot, "invalid use of '...'")
   308  		check.use(e.Elem)
   309  
   310  	case *syntax.StructType:
   311  		typ := new(Struct)
   312  		setDefType(def, typ)
   313  		check.structType(typ, e)
   314  		return typ
   315  
   316  	case *syntax.Operation:
   317  		if e.Op == syntax.Mul && e.Y == nil {
   318  			typ := new(Pointer)
   319  			typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
   320  			setDefType(def, typ)
   321  			typ.base = check.varType(e.X)
   322  			// If typ.base is invalid, it's unlikely that *base is particularly
   323  			// useful - even a valid dereferenciation will lead to an invalid
   324  			// type again, and in some cases we get unexpected follow-on errors
   325  			// (e.g., go.dev/issue/49005). Return an invalid type instead.
   326  			if !isValid(typ.base) {
   327  				return Typ[Invalid]
   328  			}
   329  			return typ
   330  		}
   331  
   332  		check.errorf(e0, NotAType, "%s is not a type", e0)
   333  		check.use(e0)
   334  
   335  	case *syntax.FuncType:
   336  		typ := new(Signature)
   337  		setDefType(def, typ)
   338  		check.funcType(typ, nil, nil, e)
   339  		return typ
   340  
   341  	case *syntax.InterfaceType:
   342  		typ := check.newInterface()
   343  		setDefType(def, typ)
   344  		check.interfaceType(typ, e, def)
   345  		return typ
   346  
   347  	case *syntax.MapType:
   348  		typ := new(Map)
   349  		setDefType(def, typ)
   350  
   351  		typ.key = check.varType(e.Key)
   352  		typ.elem = check.varType(e.Value)
   353  
   354  		// spec: "The comparison operators == and != must be fully defined
   355  		// for operands of the key type; thus the key type must not be a
   356  		// function, map, or slice."
   357  		//
   358  		// Delay this check because it requires fully setup types;
   359  		// it is safe to continue in any case (was go.dev/issue/6667).
   360  		check.later(func() {
   361  			if !Comparable(typ.key) {
   362  				var why string
   363  				if isTypeParam(typ.key) {
   364  					why = " (missing comparable constraint)"
   365  				}
   366  				check.errorf(e.Key, IncomparableMapKey, "invalid map key type %s%s", typ.key, why)
   367  			}
   368  		}).describef(e.Key, "check map key %s", typ.key)
   369  
   370  		return typ
   371  
   372  	case *syntax.ChanType:
   373  		typ := new(Chan)
   374  		setDefType(def, typ)
   375  
   376  		dir := SendRecv
   377  		switch e.Dir {
   378  		case 0:
   379  			// nothing to do
   380  		case syntax.SendOnly:
   381  			dir = SendOnly
   382  		case syntax.RecvOnly:
   383  			dir = RecvOnly
   384  		default:
   385  			check.errorf(e, InvalidSyntaxTree, "unknown channel direction %d", e.Dir)
   386  			// ok to continue
   387  		}
   388  
   389  		typ.dir = dir
   390  		typ.elem = check.varType(e.Elem)
   391  		return typ
   392  
   393  	default:
   394  		check.errorf(e0, NotAType, "%s is not a type", e0)
   395  		check.use(e0)
   396  	}
   397  
   398  	typ := Typ[Invalid]
   399  	setDefType(def, typ)
   400  	return typ
   401  }
   402  
   403  func setDefType(def *TypeName, typ Type) {
   404  	if def != nil {
   405  		switch t := def.typ.(type) {
   406  		case *Alias:
   407  			// t.fromRHS should always be set, either to an invalid type
   408  			// in the beginning, or to typ in certain cyclic declarations.
   409  			if t.fromRHS != Typ[Invalid] && t.fromRHS != typ {
   410  				panic(sprintf(nil, true, "t.fromRHS = %s, typ = %s\n", t.fromRHS, typ))
   411  			}
   412  			t.fromRHS = typ
   413  		case *Basic:
   414  			assert(t == Typ[Invalid])
   415  		case *Named:
   416  			t.underlying = typ
   417  		default:
   418  			panic(fmt.Sprintf("unexpected type %T", t))
   419  		}
   420  	}
   421  }
   422  
   423  func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def *TypeName) (res Type) {
   424  	if check.conf.Trace {
   425  		check.trace(x.Pos(), "-- instantiating type %s with %s", x, xlist)
   426  		check.indent++
   427  		defer func() {
   428  			check.indent--
   429  			// Don't format the underlying here. It will always be nil.
   430  			check.trace(x.Pos(), "=> %s", res)
   431  		}()
   432  	}
   433  
   434  	var cause string
   435  	gtyp := check.genericType(x, &cause)
   436  	if cause != "" {
   437  		check.errorf(x, NotAGenericType, invalidOp+"%s%s (%s)", x, xlist, cause)
   438  	}
   439  	if !isValid(gtyp) {
   440  		return gtyp // error already reported
   441  	}
   442  
   443  	orig := asNamed(gtyp)
   444  	if orig == nil {
   445  		panic(fmt.Sprintf("%v: cannot instantiate %v", x.Pos(), gtyp))
   446  	}
   447  
   448  	// evaluate arguments
   449  	targs := check.typeList(xlist)
   450  	if targs == nil {
   451  		setDefType(def, Typ[Invalid]) // avoid errors later due to lazy instantiation
   452  		return Typ[Invalid]
   453  	}
   454  
   455  	// create the instance
   456  	inst := asNamed(check.instance(x.Pos(), orig, targs, nil, check.context()))
   457  	setDefType(def, inst)
   458  
   459  	// orig.tparams may not be set up, so we need to do expansion later.
   460  	check.later(func() {
   461  		// This is an instance from the source, not from recursive substitution,
   462  		// and so it must be resolved during type-checking so that we can report
   463  		// errors.
   464  		check.recordInstance(x, inst.TypeArgs().list(), inst)
   465  
   466  		if check.validateTArgLen(x.Pos(), inst.obj.name, inst.TypeParams().Len(), inst.TypeArgs().Len()) {
   467  			if i, err := check.verify(x.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), check.context()); err != nil {
   468  				// best position for error reporting
   469  				pos := x.Pos()
   470  				if i < len(xlist) {
   471  					pos = syntax.StartPos(xlist[i])
   472  				}
   473  				check.softErrorf(pos, InvalidTypeArg, "%s", err)
   474  			} else {
   475  				check.mono.recordInstance(check.pkg, x.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), xlist)
   476  			}
   477  		}
   478  
   479  		// TODO(rfindley): remove this call: we don't need to call validType here,
   480  		// as cycles can only occur for types used inside a Named type declaration,
   481  		// and so it suffices to call validType from declared types.
   482  		check.validType(inst)
   483  	}).describef(x, "resolve instance %s", inst)
   484  
   485  	return inst
   486  }
   487  
   488  // arrayLength type-checks the array length expression e
   489  // and returns the constant length >= 0, or a value < 0
   490  // to indicate an error (and thus an unknown length).
   491  func (check *Checker) arrayLength(e syntax.Expr) int64 {
   492  	// If e is an identifier, the array declaration might be an
   493  	// attempt at a parameterized type declaration with missing
   494  	// constraint. Provide an error message that mentions array
   495  	// length.
   496  	if name, _ := e.(*syntax.Name); name != nil {
   497  		obj := check.lookup(name.Value)
   498  		if obj == nil {
   499  			check.errorf(name, InvalidArrayLen, "undefined array length %s or missing type constraint", name.Value)
   500  			return -1
   501  		}
   502  		if _, ok := obj.(*Const); !ok {
   503  			check.errorf(name, InvalidArrayLen, "invalid array length %s", name.Value)
   504  			return -1
   505  		}
   506  	}
   507  
   508  	var x operand
   509  	check.expr(nil, &x, e)
   510  	if x.mode != constant_ {
   511  		if x.mode != invalid {
   512  			check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
   513  		}
   514  		return -1
   515  	}
   516  
   517  	if isUntyped(x.typ) || isInteger(x.typ) {
   518  		if val := constant.ToInt(x.val); val.Kind() == constant.Int {
   519  			if representableConst(val, check, Typ[Int], nil) {
   520  				if n, ok := constant.Int64Val(val); ok && n >= 0 {
   521  					return n
   522  				}
   523  			}
   524  		}
   525  	}
   526  
   527  	var msg string
   528  	if isInteger(x.typ) {
   529  		msg = "invalid array length %s"
   530  	} else {
   531  		msg = "array length %s must be integer"
   532  	}
   533  	check.errorf(&x, InvalidArrayLen, msg, &x)
   534  	return -1
   535  }
   536  
   537  // typeList provides the list of types corresponding to the incoming expression list.
   538  // If an error occurred, the result is nil, but all list elements were type-checked.
   539  func (check *Checker) typeList(list []syntax.Expr) []Type {
   540  	res := make([]Type, len(list)) // res != nil even if len(list) == 0
   541  	for i, x := range list {
   542  		t := check.varType(x)
   543  		if !isValid(t) {
   544  			res = nil
   545  		}
   546  		if res != nil {
   547  			res[i] = t
   548  		}
   549  	}
   550  	return res
   551  }
   552  

View as plain text