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