parse_type.mx raw

   1  package syntax
   2  
   3  import (
   4  	"unsafe"
   5  	"git.smesh.lol/moxie/pkg/token"
   6  )
   7  
   8  func (p *Parser) type_() (e Expr) {
   9  	if trace {
  10  		defer p.trace("type_")()
  11  	}
  12  
  13  	typ := p.typeOrNil()
  14  	if typ == nil {
  15  		typ = p.badExpr()
  16  		p.syntaxError("expected type")
  17  		p.advance(token.Comma, token.Colon, token.Semi, token.Rparen, token.Rbrack, token.Rbrace)
  18  	}
  19  
  20  	return typ
  21  }
  22  
  23  func newIndirect(pos token.Pos, typ Expr) (e Expr) {
  24  	oc := &Operation{}
  25  	oc.pos = pos
  26  	oc.Op = token.Mul
  27  	oc.X = typ
  28  	return oc
  29  }
  30  
  31  // typeOrNil is like type_ but it returns nil if there was no type
  32  // instead of reporting an error.
  33  //
  34  //	Type     = TypeName | TypeLit + "(" Type ")" .
  35  //	TypeName = identifier | QualifiedIdent .
  36  //	TypeLit  = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
  37  //		      SliceType | MapType | Channel_Type .
  38  func (p *Parser) typeOrNil() (e Expr) {
  39  	if trace {
  40  		defer p.trace("typeOrNil")()
  41  	}
  42  
  43  	pos := p.pos()
  44  	switch p.Tok {
  45  	case token.Star:
  46  		// ptrtype
  47  		p.Next()
  48  		return newIndirect(pos, p.type_())
  49  
  50  	case token.Arrow:
  51  		// recvchantype
  52  		p.Next()
  53  		p.want(token.Chan)
  54  		t := (*ChanType)(p.nodeAlloc(unsafe.Sizeof(ChanType{})))
  55  		t.pos = pos
  56  		t.Dir = RecvOnly
  57  		t.Elem = p.chanElem()
  58  		return t
  59  
  60  	case token.Func:
  61  		// fntype
  62  		p.Next()
  63  		_, t := p.funcType("function type")
  64  		return t
  65  
  66  	case token.Lbrack:
  67  		// '[' oexpr ']' ntype
  68  		// '[' _DotDotDot ']' ntype
  69  		p.Next()
  70  		if p.got(token.Rbrack) {
  71  			return p.sliceType(pos)
  72  		}
  73  		return p.arrayType(pos, nil)
  74  
  75  	case token.Chan:
  76  		// _Chan non_recvchantype
  77  		// _Chan _Comm ntype
  78  		p.Next()
  79  		t := (*ChanType)(p.nodeAlloc(unsafe.Sizeof(ChanType{})))
  80  		t.pos = pos
  81  		if p.got(token.Arrow) {
  82  			t.Dir = SendOnly
  83  		}
  84  		t.Elem = p.chanElem()
  85  		return t
  86  
  87  	case token.Map:
  88  		// _Map '[' ntype ']' ntype
  89  		p.Next()
  90  		p.want(token.Lbrack)
  91  		t := (*MapType)(p.nodeAlloc(unsafe.Sizeof(MapType{})))
  92  		t.pos = pos
  93  		t.Key = p.type_()
  94  		p.want(token.Rbrack)
  95  		t.Value = p.type_()
  96  		return t
  97  
  98  	case token.Struct:
  99  		return p.structType()
 100  
 101  	case token.Interface:
 102  		return p.interfaceType()
 103  
 104  	case token.NameType:
 105  		return p.qualifiedName(nil)
 106  
 107  	case token.Lparen:
 108  		p.Next()
 109  		t := p.type_()
 110  		p.want(token.Rparen)
 111  		// The parser doesn't keep unnecessary parentheses.
 112  		// Set the flag below to keep them, for testing
 113  		// (see e.g. tests for go.dev/issue/68639).
 114  		const keep_parens = false
 115  		if keep_parens {
 116  			px := (*ParenExpr)(p.nodeAlloc(unsafe.Sizeof(ParenExpr{})))
 117  			px.pos = pos
 118  			px.X = t
 119  			t = px
 120  		}
 121  		return t
 122  	}
 123  
 124  	return nil
 125  }
 126  
 127  func (p *Parser) typeInstance(typ Expr) (e Expr) {
 128  	if trace {
 129  		defer p.trace("typeInstance")()
 130  	}
 131  
 132  	pos := p.pos()
 133  	p.want(token.Lbrack)
 134  	x := (*IndexExpr)(p.nodeAlloc(unsafe.Sizeof(IndexExpr{})))
 135  	x.pos = pos
 136  	x.X = typ
 137  	if p.Tok == token.Rbrack {
 138  		p.syntaxError("expected type argument list")
 139  		x.Index = p.badExpr()
 140  	} else {
 141  		x.Index, _ = p.typeList(true)
 142  	}
 143  	p.want(token.Rbrack)
 144  	return x
 145  }
 146  
 147  // If context != "", type parameters are not permitted.
 148  func (p *Parser) funcType(context string) (tparams []*Field, ft *FuncType) {
 149  	if trace {
 150  		defer p.trace("funcType")()
 151  	}
 152  	typ := (*FuncType)(p.nodeAlloc(unsafe.Sizeof(FuncType{})))
 153  	typ.pos = p.pos()
 154  
 155  	var tparamList []*Field
 156  	if p.got(token.Lbrack) {
 157  		if context != "" {
 158  			// accept but complain
 159  			p.syntaxErrorAt(typ.pos, context | " must have no type parameters")
 160  		}
 161  		if p.Tok == token.Rbrack {
 162  			p.syntaxError("empty type parameter list")
 163  			p.Next()
 164  		} else {
 165  			tparamList = p.paramList(nil, nil, token.Rbrack, true, false)
 166  		}
 167  	}
 168  
 169  	p.want(token.Lparen)
 170  	typ.ParamList = p.paramList(nil, nil, token.Rparen, false, true)
 171  	typ.ResultList = p.funcResult()
 172  
 173  	return tparamList, typ
 174  }
 175  
 176  // "[" has already been consumed, and pos is its position.
 177  // If arrLen != nil it is the already consumed array length.
 178  func (p *Parser) arrayType(pos token.Pos, arrLen Expr) (e Expr) {
 179  	if trace {
 180  		defer p.trace("arrayType")()
 181  	}
 182  
 183  	if arrLen == nil && !p.got(token.DotDotDot) {
 184  		p.Xnest++
 185  		arrLen = p.expr()
 186  		p.Xnest--
 187  	}
 188  	if p.Tok == token.Comma {
 189  		// Trailing commas are accepted in type parameter
 190  		// lists but not in array type declarations.
 191  		// Accept for better error handling but complain.
 192  		p.syntaxError("unexpected comma; expected ]")
 193  		p.Next()
 194  	}
 195  	p.want(token.Rbrack)
 196  	at := (*ArrayType)(p.nodeAlloc(unsafe.Sizeof(ArrayType{})))
 197  	at.pos = pos
 198  	at.Len = arrLen
 199  	at.Elem = p.type_()
 200  	return at
 201  }
 202  
 203  // "[" and "]" have already been consumed, and pos is the position of "[".
 204  func (p *Parser) sliceType(pos token.Pos) (e Expr) {
 205  	tc := (*SliceType)(p.nodeAlloc(unsafe.Sizeof(SliceType{})))
 206  	tc.pos = pos
 207  	tc.Elem = p.type_()
 208  	return tc
 209  }
 210  
 211  func (p *Parser) chanElem() (e Expr) {
 212  	if trace {
 213  		defer p.trace("chanElem")()
 214  	}
 215  
 216  	typ := p.typeOrNil()
 217  	if typ == nil {
 218  		typ = p.badExpr()
 219  		p.syntaxError("missing channel element type")
 220  		// assume element type is simply absent - don't advance
 221  	}
 222  
 223  	return typ
 224  }
 225  
 226  // StructType = "struct" "{" { FieldDecl ";" } "}" .
 227  func (p *Parser) structType() (s *StructType) {
 228  	if trace {
 229  		defer p.trace("structType")()
 230  	}
 231  
 232  	typ := (*StructType)(p.nodeAlloc(unsafe.Sizeof(StructType{})))
 233  	typ.pos = p.pos()
 234  
 235  	p.want(token.Struct)
 236  	p.want(token.Lbrace)
 237  	p.list("struct type", token.Semi, token.Rbrace, func() bool {
 238  		p.fieldDecl(typ)
 239  		return false
 240  	})
 241  
 242  	return typ
 243  }
 244  
 245  // InterfaceType = "interface" "{" { ( MethodDecl | EmbeddedElem ) ";" } "}" .
 246  func (p *Parser) interfaceType() (i *InterfaceType) {
 247  	if trace {
 248  		defer p.trace("interfaceType")()
 249  	}
 250  
 251  	typ := (*InterfaceType)(p.nodeAlloc(unsafe.Sizeof(InterfaceType{})))
 252  	typ.pos = p.pos()
 253  
 254  	p.want(token.Interface)
 255  	p.want(token.Lbrace)
 256  	p.list("interface type", token.Semi, token.Rbrace, func() bool {
 257  		var f *Field
 258  		if p.Tok == token.NameType {
 259  			f = p.methodDecl()
 260  		}
 261  		if f == nil || f.Name == nil {
 262  			f = p.embeddedElem(f)
 263  		}
 264  		push(typ.MethodList, f)
 265  		return false
 266  	})
 267  
 268  	return typ
 269  }
 270  
 271  // Result = Parameters | Type .
 272  func (p *Parser) funcResult() (fs []*Field) {
 273  	if trace {
 274  		defer p.trace("funcResult")()
 275  	}
 276  
 277  	if p.got(token.Lparen) {
 278  		return p.paramList(nil, nil, token.Rparen, false, false)
 279  	}
 280  
 281  	pos := p.pos()
 282  	if typ := p.typeOrNil(); typ != nil {
 283  		f := (*Field)(p.nodeAlloc(unsafe.Sizeof(Field{})))
 284  		f.pos = pos
 285  		f.Type = typ
 286  		return []*Field{f}
 287  	}
 288  
 289  	return nil
 290  }
 291  
 292  func (p *Parser) addField(styp *StructType, pos token.Pos, name *Name, typ Expr, tag *BasicLit) {
 293  	if tag != nil {
 294  		for i := len(styp.FieldList) - len(styp.TagList); i > 0; i-- {
 295  			push(styp.TagList, nil)
 296  		}
 297  		push(styp.TagList, tag)
 298  	}
 299  
 300  	f := (*Field)(p.nodeAlloc(unsafe.Sizeof(Field{})))
 301  	f.pos = pos
 302  	f.Name = name
 303  	f.Type = typ
 304  	push(styp.FieldList, f)
 305  
 306  	if debug && tag != nil && len(styp.FieldList) != len(styp.TagList) {
 307  		panic("inconsistent struct field list")
 308  	}
 309  }
 310  
 311  // FieldDecl      = (IdentifierList Type | AnonymousField) [ Tag ] .
 312  // AnonymousField = [ "*" ] TypeName .
 313  // Tag            = string_lit .
 314  func (p *Parser) fieldDecl(styp *StructType) {
 315  	if trace {
 316  		defer p.trace("fieldDecl")()
 317  	}
 318  
 319  	pos := p.pos()
 320  	switch p.Tok {
 321  	case token.NameType:
 322  		name := p.name()
 323  		if p.Tok == token.Dot || p.Tok == token.Literal || p.Tok == token.Semi || p.Tok == token.Rbrace {
 324  			// embedded type
 325  			embedTyp := p.qualifiedName(name)
 326  			embedTag := p.oliteral()
 327  			p.addField(styp, pos, nil, embedTyp, embedTag)
 328  			break
 329  		}
 330  
 331  		// name1, name2, ... Type [ tag ]
 332  		names := p.nameList(name)
 333  		var typ Expr
 334  
 335  		// Careful dance: We don't know if we have an embedded instantiated
 336  		// type T[P1, P2, ...] or a field T of array/slice type [P]E or []E.
 337  		if len(names) == 1 && p.Tok == token.Lbrack {
 338  			typ = p.arrayOrTArgs()
 339  			if idxTyp, ok := typ.(*IndexExpr); ok {
 340  				// embedded type T[P1, P2, ...]
 341  				idxTyp.X = name // name == names[0]
 342  				idxTag := p.oliteral()
 343  				p.addField(styp, pos, nil, idxTyp, idxTag)
 344  				break
 345  			}
 346  		} else {
 347  			// T P
 348  			typ = p.type_()
 349  		}
 350  
 351  		tag := p.oliteral()
 352  
 353  		for _, nm := range names {
 354  			p.addField(styp, nm.Pos(), nm, typ, tag)
 355  		}
 356  
 357  	case token.Star:
 358  		p.Next()
 359  		var typ Expr
 360  		if p.Tok == token.Lparen {
 361  			// *(T)
 362  			p.syntaxError("cannot parenthesize embedded type")
 363  			p.Next()
 364  			typ = p.qualifiedName(nil)
 365  			p.got(token.Rparen) // no need to complain if missing
 366  		} else {
 367  			// *T
 368  			typ = p.qualifiedName(nil)
 369  		}
 370  		tag := p.oliteral()
 371  		p.addField(styp, pos, nil, newIndirect(pos, typ), tag)
 372  
 373  	case token.Lparen:
 374  		p.syntaxError("cannot parenthesize embedded type")
 375  		p.Next()
 376  		var typ Expr
 377  		if p.Tok == token.Star {
 378  			// (*T)
 379  			starPos := p.pos()
 380  			p.Next()
 381  			typ = newIndirect(starPos, p.qualifiedName(nil))
 382  		} else {
 383  			// (T)
 384  			typ = p.qualifiedName(nil)
 385  		}
 386  		p.got(token.Rparen) // no need to complain if missing
 387  		tag := p.oliteral()
 388  		p.addField(styp, pos, nil, typ, tag)
 389  
 390  	default:
 391  		p.syntaxError("expected field name or embedded type")
 392  		p.advance(token.Semi, token.Rbrace)
 393  	}
 394  }
 395  
 396  func (p *Parser) arrayOrTArgs() (e Expr) {
 397  	if trace {
 398  		defer p.trace("arrayOrTArgs")()
 399  	}
 400  
 401  	pos := p.pos()
 402  	p.want(token.Lbrack)
 403  	if p.got(token.Rbrack) {
 404  		return p.sliceType(pos)
 405  	}
 406  
 407  	// x [n]E or x[n,], x[n1, n2], ...
 408  	n, comma := p.typeList(false)
 409  	p.want(token.Rbrack)
 410  	if !comma {
 411  		if elem := p.typeOrNil(); elem != nil {
 412  			// x [n]E
 413  			arrT := (*ArrayType)(p.nodeAlloc(unsafe.Sizeof(ArrayType{})))
 414  			arrT.pos = pos
 415  			arrT.Len = n
 416  			arrT.Elem = elem
 417  			return arrT
 418  		}
 419  	}
 420  
 421  	// x[n,], x[n1, n2], ...
 422  	idxT := (*IndexExpr)(p.nodeAlloc(unsafe.Sizeof(IndexExpr{})))
 423  	idxT.pos = pos
 424  	// idxT.X will be filled in by caller
 425  	idxT.Index = n
 426  	return idxT
 427  }
 428  
 429  func (p *Parser) oliteral() (b *BasicLit) {
 430  	if p.Tok == token.Literal {
 431  		b = (*BasicLit)(p.nodeAlloc(unsafe.Sizeof(BasicLit{})))
 432  		b.pos = p.pos()
 433  		b.Value = p.Lit
 434  		b.Kind = p.Kind
 435  		b.Bad = p.Bad
 436  		p.Next()
 437  		return b
 438  	}
 439  	return nil
 440  }
 441  
 442  // MethodSpec        = MethodName Signature | InterfaceTypeName .
 443  // MethodName        = identifier .
 444  // InterfaceTypeName = TypeName .
 445  func (p *Parser) methodDecl() (f *Field) {
 446  	if trace {
 447  		defer p.trace("methodDecl")()
 448  	}
 449  
 450  	f := (*Field)(p.nodeAlloc(unsafe.Sizeof(Field{})))
 451  	f.pos = p.pos()
 452  	name := p.name()
 453  
 454  	const context = "interface method"
 455  
 456  	switch p.Tok {
 457  	case token.Lparen:
 458  		// method
 459  		f.Name = name
 460  		_, f.Type = p.funcType(context)
 461  
 462  	case token.Lbrack:
 463  		// Careful dance: We don't know if we have a generic method m[T C](x T)
 464  		// or an embedded instantiated type T[P1, P2] (we accept generic methods
 465  		// for generality and robustness of parsing but complain with an error).
 466  		pos := p.pos()
 467  		p.Next()
 468  
 469  		// Empty type parameter or argument lists are not permitted.
 470  		// Treat as if [] were absent.
 471  		if p.Tok == token.Rbrack {
 472  			// name[]
 473  			rbPos := p.pos()
 474  			p.Next()
 475  			if p.Tok == token.Lparen {
 476  				// name[](
 477  				p.errorAt(rbPos, "empty type parameter list")
 478  				f.Name = name
 479  				_, f.Type = p.funcType(context)
 480  			} else {
 481  				p.errorAt(rbPos, "empty type argument list")
 482  				f.Type = name
 483  			}
 484  			break
 485  		}
 486  
 487  		// A type argument list looks like a parameter list with only
 488  		// types. Parse a parameter list and decide afterwards.
 489  		list := p.paramList(nil, nil, token.Rbrack, false, false)
 490  		if len(list) == 0 {
 491  			// The type parameter list is not [] but we got nothing
 492  			// due to other errors (reported by paramList). Treat
 493  			// as if [] were absent.
 494  			if p.Tok == token.Lparen {
 495  				f.Name = name
 496  				_, f.Type = p.funcType(context)
 497  			} else {
 498  				f.Type = name
 499  			}
 500  			break
 501  		}
 502  
 503  		// len(list) > 0
 504  		if list[0].Name != nil {
 505  			// generic method
 506  			f.Name = name
 507  			_, f.Type = p.funcType(context)
 508  			p.errorAt(pos, "interface method must have no type parameters")
 509  			break
 510  		}
 511  
 512  		// embedded instantiated type
 513  		t := (*IndexExpr)(p.nodeAlloc(unsafe.Sizeof(IndexExpr{})))
 514  		t.pos = pos
 515  		t.X = name
 516  		if len(list) == 1 {
 517  			t.Index = list[0].Type
 518  		} else {
 519  			// len(list) > 1
 520  			l := (*ListExpr)(p.nodeAlloc(unsafe.Sizeof(ListExpr{})))
 521  			l.pos = list[0].Pos()
 522  			l.ElemList = []Expr{:len(list)}
 523  			for i := range list {
 524  				l.ElemList[i] = list[i].Type
 525  			}
 526  			t.Index = l
 527  		}
 528  		f.Type = t
 529  
 530  	default:
 531  		// embedded type
 532  		f.Type = p.qualifiedName(name)
 533  	}
 534  
 535  	return f
 536  }
 537  
 538  // EmbeddedElem = MethodSpec | EmbeddedTerm { "|" EmbeddedTerm } .
 539  func (p *Parser) embeddedElem(f *Field) (fv *Field) {
 540  	if trace {
 541  		defer p.trace("embeddedElem")()
 542  	}
 543  
 544  	if f == nil {
 545  		f = (*Field)(p.nodeAlloc(unsafe.Sizeof(Field{})))
 546  		f.pos = p.pos()
 547  		f.Type = p.embeddedTerm()
 548  	}
 549  
 550  	for p.Tok == token.OperatorType && p.Op == token.Or {
 551  		t := (*Operation)(p.nodeAlloc(unsafe.Sizeof(Operation{})))
 552  		t.pos = p.pos()
 553  		t.Op = token.Or
 554  		p.Next()
 555  		t.X = f.Type
 556  		t.Y = p.embeddedTerm()
 557  		f.Type = t
 558  	}
 559  
 560  	return f
 561  }
 562  
 563  // EmbeddedTerm = [ "~" ] Type .
 564  func (p *Parser) embeddedTerm() (e Expr) {
 565  	if trace {
 566  		defer p.trace("embeddedTerm")()
 567  	}
 568  
 569  	if p.Tok == token.OperatorType && p.Op == token.Tilde {
 570  		op := (*Operation)(p.nodeAlloc(unsafe.Sizeof(Operation{})))
 571  		op.pos = p.pos()
 572  		op.Op = token.Tilde
 573  		p.Next()
 574  		op.X = p.type_()
 575  		return op
 576  	}
 577  
 578  	et := p.typeOrNil()
 579  	if et == nil {
 580  		et = p.badExpr()
 581  		p.syntaxError("expected ~ term or type")
 582  		p.advance(token.OperatorType, token.Semi, token.Rparen, token.Rbrack, token.Rbrace)
 583  	}
 584  
 585  	return et
 586  }
 587  
 588  // ParameterDecl = [ IdentifierList ] [ "..." ] Type .
 589  func (p *Parser) paramDeclOrNil(name *Name, follow token.Token) (f *Field) {
 590  	if trace {
 591  		defer p.trace("paramDeclOrNil")()
 592  	}
 593  
 594  	// type set notation is ok in type parameter lists
 595  	typeSetsOk := follow == token.Rbrack
 596  
 597  	pos := p.pos()
 598  	if name != nil {
 599  		pos = name.pos
 600  	} else if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Tilde {
 601  		// "~" ...
 602  		return p.embeddedElem(nil)
 603  	}
 604  
 605  	f := (*Field)(p.nodeAlloc(unsafe.Sizeof(Field{})))
 606  	f.pos = pos
 607  
 608  	if p.Tok == token.NameType || name != nil {
 609  		// name
 610  		if name == nil {
 611  			name = p.name()
 612  		}
 613  
 614  		if p.Tok == token.Lbrack {
 615  			// name "[" ...
 616  			f.Type = p.arrayOrTArgs()
 617  			if typ, ok := f.Type.(*IndexExpr); ok {
 618  				// name "[" ... "]"
 619  				typ.X = name
 620  			} else {
 621  				// name "[" n "]" E
 622  				f.Name = name
 623  			}
 624  			if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or {
 625  				// name "[" ... "]" "|" ...
 626  				// name "[" n "]" E "|" ...
 627  				f = p.embeddedElem(f)
 628  			}
 629  			return f
 630  		}
 631  
 632  		if p.Tok == token.Dot {
 633  			// name "." ...
 634  			f.Type = p.qualifiedName(name)
 635  			if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or {
 636  				// name "." name "|" ...
 637  				f = p.embeddedElem(f)
 638  			}
 639  			return f
 640  		}
 641  
 642  		if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or {
 643  			// name "|" ...
 644  			f.Type = name
 645  			return p.embeddedElem(f)
 646  		}
 647  
 648  		f.Name = name
 649  	}
 650  
 651  	if p.Tok == token.DotDotDot {
 652  		// [name] "..." ...
 653  		t := (*DotsType)(p.nodeAlloc(unsafe.Sizeof(DotsType{})))
 654  		t.pos = p.pos()
 655  		p.Next()
 656  		t.Elem = p.typeOrNil()
 657  		if t.Elem == nil {
 658  			f.Type = p.badExpr()
 659  			p.syntaxError("... is missing type")
 660  		} else {
 661  			f.Type = t
 662  		}
 663  		return f
 664  	}
 665  
 666  	if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Tilde {
 667  		// [name] "~" ...
 668  		f.Type = p.embeddedElem(nil).Type
 669  		return f
 670  	}
 671  
 672  	f.Type = p.typeOrNil()
 673  	if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or && f.Type != nil {
 674  		// [name] type "|"
 675  		f = p.embeddedElem(f)
 676  	}
 677  	if f.Name != nil || f.Type != nil {
 678  		return f
 679  	}
 680  
 681  	p.syntaxError("expected " | tokstring(follow))
 682  	p.advance(token.Comma, follow)
 683  	return nil
 684  }
 685  
 686  // Parameters    = "(" [ ParameterList [ "," ] ] ")" .
 687  // ParameterList = ParameterDecl { "," ParameterDecl } .
 688  // "(" or "[" has already been consumed.
 689  // If name != nil, it is the first name after "(" or "[".
 690  // If typ != nil, name must be != nil, and (name, typ) is the first field in the list.
 691  // In the result list, either all fields have a name, or no field has a name.
 692  func (p *Parser) paramList(name *Name, typ Expr, closeTok token.Token, requireNames, dddok bool) (list []*Field) {
 693  	if trace {
 694  		defer p.trace("paramList")()
 695  	}
 696  
 697  	// p.list won't invoke its function argument if we're at the end of the
 698  	// parameter list. If we have a complete field, handle this case here.
 699  	if name != nil && typ != nil && p.Tok == closeTok {
 700  		p.Next()
 701  		par := (*Field)(p.nodeAlloc(unsafe.Sizeof(Field{})))
 702  		par.pos = name.pos
 703  		par.Name = name
 704  		par.Type = typ
 705  		return []*Field{par}
 706  	}
 707  
 708  	var named int32 // number of parameters that have an explicit name and type
 709  	var typed int32 // number of parameters that have an explicit type
 710  	end := p.list("parameter list", token.Comma, closeTok, func() bool {
 711  		var par *Field
 712  		if typ != nil {
 713  			if debug && name == nil {
 714  				panic("initial type provided without name")
 715  			}
 716  			par = (*Field)(p.nodeAlloc(unsafe.Sizeof(Field{})))
 717  			par.pos = name.pos
 718  			par.Name = name
 719  			par.Type = typ
 720  		} else {
 721  			par = p.paramDeclOrNil(name, closeTok)
 722  		}
 723  		name = nil // 1st name was consumed if present
 724  		typ = nil  // 1st type was consumed if present
 725  		if par != nil {
 726  			if debug && par.Name == nil && par.Type == nil {
 727  				panic("parameter without name or type")
 728  			}
 729  			if par.Name != nil && par.Type != nil {
 730  				named++
 731  			}
 732  			if par.Type != nil {
 733  				typed++
 734  			}
 735  			push(list, par)
 736  		}
 737  		return false
 738  	})
 739  
 740  	if len(list) == 0 {
 741  		return
 742  	}
 743  
 744  	// distribute parameter types (len(list) > 0)
 745  	if named == 0 && !requireNames {
 746  		// all unnamed and we're not in a type parameter list => found names are named types
 747  		for _, par := range list {
 748  			if parTyp := par.Name; parTyp != nil {
 749  				par.Type = parTyp
 750  				par.Name = nil
 751  			}
 752  		}
 753  	} else if named != len(list) {
 754  		// some named or we're in a type parameter list => all must be named
 755  		var errPos token.Pos // left-most error position (or unknown)
 756  		var curTyp Expr   // current type (from right to left)
 757  		for i := len(list) - 1; i >= 0; i-- {
 758  			par := list[i]
 759  			if par.Type != nil {
 760  				curTyp = par.Type
 761  				if par.Name == nil {
 762  					errPos = StartPos(curTyp)
 763  					par.Name = NewName(errPos, "_")
 764  				}
 765  			} else if curTyp != nil {
 766  				par.Type = curTyp
 767  			} else {
 768  				// par.Type == nil && typ == nil => we only have a par.Name
 769  				errPos = par.Name.Pos()
 770  				t := p.badExpr()
 771  				t.pos = errPos // correct position
 772  				par.Type = t
 773  			}
 774  		}
 775  		if errPos.IsKnown() {
 776  			// Not all parameters are named because named != len(list).
 777  			// If named == typed, there must be parameters that have no types.
 778  			// They must be at the end of the parameter list, otherwise types
 779  			// would have been filled in by the right-to-left sweep above and
 780  			// there would be no error.
 781  			// If requireNames is set, the parameter list is a type parameter
 782  			// list.
 783  			var msg string
 784  			if named == typed {
 785  				errPos = end // position error at closing token ) or ]
 786  				if requireNames {
 787  					msg = "missing type constraint"
 788  				} else {
 789  					msg = "missing parameter type"
 790  				}
 791  			} else {
 792  				if requireNames {
 793  					msg = "missing type parameter name"
 794  					// go.dev/issue/60812
 795  					if len(list) == 1 {
 796  						msg = msg | " or invalid array length"
 797  					}
 798  				} else {
 799  					msg = "missing parameter name"
 800  				}
 801  			}
 802  			p.syntaxErrorAt(errPos, msg)
 803  		}
 804  	}
 805  
 806  	// check use of ... - DISABLED for gen1 debugging
 807  
 808  	return
 809  }
 810  
 811  func (p *Parser) badExpr() (b *BadExpr) {
 812  	b := (*BadExpr)(p.nodeAlloc(unsafe.Sizeof(BadExpr{})))
 813  	b.pos = p.pos()
 814  	return b
 815  }
 816