1  
     2  
     3  
     4  
     5  
     6  
     7  package types2
     8  
     9  import (
    10  	"cmd/compile/internal/syntax"
    11  	. "internal/types/errors"
    12  	"strings"
    13  )
    14  
    15  
    16  
    17  func (check *Checker) langCompat(lit *syntax.BasicLit) {
    18  	s := lit.Value
    19  	if len(s) <= 2 || check.allowVersion(go1_13) {
    20  		return
    21  	}
    22  	
    23  	if strings.Contains(s, "_") {
    24  		check.versionErrorf(lit, go1_13, "underscore in numeric literal")
    25  		return
    26  	}
    27  	if s[0] != '0' {
    28  		return
    29  	}
    30  	radix := s[1]
    31  	if radix == 'b' || radix == 'B' {
    32  		check.versionErrorf(lit, go1_13, "binary literal")
    33  		return
    34  	}
    35  	if radix == 'o' || radix == 'O' {
    36  		check.versionErrorf(lit, go1_13, "0o/0O-style octal literal")
    37  		return
    38  	}
    39  	if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
    40  		check.versionErrorf(lit, go1_13, "hexadecimal floating-point literal")
    41  	}
    42  }
    43  
    44  func (check *Checker) basicLit(x *operand, e *syntax.BasicLit) {
    45  	switch e.Kind {
    46  	case syntax.IntLit, syntax.FloatLit, syntax.ImagLit:
    47  		check.langCompat(e)
    48  		
    49  		
    50  		
    51  		
    52  		
    53  		
    54  		
    55  		
    56  		
    57  		const limit = 10000
    58  		if len(e.Value) > limit {
    59  			check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
    60  			x.mode = invalid
    61  			return
    62  		}
    63  	}
    64  	x.setConst(e.Kind, e.Value)
    65  	if x.mode == invalid {
    66  		
    67  		
    68  		
    69  		
    70  		check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
    71  		x.mode = invalid
    72  		return
    73  	}
    74  	
    75  	x.expr = e 
    76  	check.overflow(x, opPos(x.expr))
    77  }
    78  
    79  func (check *Checker) funcLit(x *operand, e *syntax.FuncLit) {
    80  	if sig, ok := check.typ(e.Type).(*Signature); ok {
    81  		
    82  		
    83  		sig.scope.pos = e.Pos()
    84  		sig.scope.end = endPos(e)
    85  		if !check.conf.IgnoreFuncBodies && e.Body != nil {
    86  			
    87  			
    88  			
    89  			decl := check.decl 
    90  			iota := check.iota 
    91  			
    92  			
    93  			
    94  			
    95  			check.later(func() {
    96  				check.funcBody(decl, "<function literal>", sig, e.Body, iota)
    97  			}).describef(e, "func literal")
    98  		}
    99  		x.mode = value
   100  		x.typ = sig
   101  	} else {
   102  		check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e)
   103  		x.mode = invalid
   104  	}
   105  }
   106  
   107  func (check *Checker) compositeLit(x *operand, e *syntax.CompositeLit, hint Type) {
   108  	var typ, base Type
   109  	var isElem bool 
   110  
   111  	switch {
   112  	case e.Type != nil:
   113  		
   114  		
   115  		
   116  		if atyp, _ := e.Type.(*syntax.ArrayType); atyp != nil && isdddArray(atyp) {
   117  			
   118  			
   119  			
   120  			typ = &Array{len: -1, elem: check.varType(atyp.Elem)}
   121  			base = typ
   122  			break
   123  		}
   124  		typ = check.typ(e.Type)
   125  		base = typ
   126  
   127  	case hint != nil:
   128  		
   129  		typ = hint
   130  		base = typ
   131  		
   132  		u, _ := commonUnder(base, nil)
   133  		if b, ok := deref(u); ok {
   134  			base = b
   135  		}
   136  		isElem = true
   137  
   138  	default:
   139  		
   140  		check.error(e, UntypedLit, "missing type in composite literal")
   141  		
   142  		typ = Typ[Invalid]
   143  		base = typ
   144  	}
   145  
   146  	switch u, _ := commonUnder(base, nil); utyp := u.(type) {
   147  	case *Struct:
   148  		
   149  		
   150  		if utyp.fields == nil {
   151  			check.error(e, InvalidTypeCycle, "invalid recursive type")
   152  			x.mode = invalid
   153  			return
   154  		}
   155  		if len(e.ElemList) == 0 {
   156  			break
   157  		}
   158  		
   159  		
   160  		
   161  		fields := utyp.fields
   162  		if _, ok := e.ElemList[0].(*syntax.KeyValueExpr); ok {
   163  			
   164  			visited := make([]bool, len(fields))
   165  			for _, e := range e.ElemList {
   166  				kv, _ := e.(*syntax.KeyValueExpr)
   167  				if kv == nil {
   168  					check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
   169  					continue
   170  				}
   171  				key, _ := kv.Key.(*syntax.Name)
   172  				
   173  				
   174  				check.expr(nil, x, kv.Value)
   175  				if key == nil {
   176  					check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
   177  					continue
   178  				}
   179  				i := fieldIndex(fields, check.pkg, key.Value, false)
   180  				if i < 0 {
   181  					var alt Object
   182  					if j := fieldIndex(fields, check.pkg, key.Value, true); j >= 0 {
   183  						alt = fields[j]
   184  					}
   185  					msg := check.lookupError(base, key.Value, alt, true)
   186  					check.error(kv.Key, MissingLitField, msg)
   187  					continue
   188  				}
   189  				fld := fields[i]
   190  				check.recordUse(key, fld)
   191  				etyp := fld.typ
   192  				check.assignment(x, etyp, "struct literal")
   193  				
   194  				if visited[i] {
   195  					check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Value)
   196  					continue
   197  				}
   198  				visited[i] = true
   199  			}
   200  		} else {
   201  			
   202  			for i, e := range e.ElemList {
   203  				if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
   204  					check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
   205  					continue
   206  				}
   207  				check.expr(nil, x, e)
   208  				if i >= len(fields) {
   209  					check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
   210  					break 
   211  				}
   212  				
   213  				fld := fields[i]
   214  				if !fld.Exported() && fld.pkg != check.pkg {
   215  					check.errorf(x, UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
   216  					continue
   217  				}
   218  				etyp := fld.typ
   219  				check.assignment(x, etyp, "struct literal")
   220  			}
   221  			if len(e.ElemList) < len(fields) {
   222  				check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
   223  				
   224  			}
   225  		}
   226  
   227  	case *Array:
   228  		
   229  		
   230  		
   231  		if utyp.elem == nil {
   232  			check.error(e, InvalidTypeCycle, "invalid recursive type")
   233  			x.mode = invalid
   234  			return
   235  		}
   236  		n := check.indexedElts(e.ElemList, utyp.elem, utyp.len)
   237  		
   238  		
   239  		
   240  		
   241  		
   242  		
   243  		
   244  		
   245  		if utyp.len < 0 {
   246  			utyp.len = n
   247  			
   248  			
   249  			
   250  			
   251  			if e.Type != nil {
   252  				check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
   253  			}
   254  		}
   255  
   256  	case *Slice:
   257  		
   258  		
   259  		if utyp.elem == nil {
   260  			check.error(e, InvalidTypeCycle, "invalid recursive type")
   261  			x.mode = invalid
   262  			return
   263  		}
   264  		check.indexedElts(e.ElemList, utyp.elem, -1)
   265  
   266  	case *Map:
   267  		
   268  		
   269  		if utyp.key == nil || utyp.elem == nil {
   270  			check.error(e, InvalidTypeCycle, "invalid recursive type")
   271  			x.mode = invalid
   272  			return
   273  		}
   274  		
   275  		
   276  		
   277  		keyIsInterface := isNonTypeParamInterface(utyp.key)
   278  		visited := make(map[any][]Type, len(e.ElemList))
   279  		for _, e := range e.ElemList {
   280  			kv, _ := e.(*syntax.KeyValueExpr)
   281  			if kv == nil {
   282  				check.error(e, MissingLitKey, "missing key in map literal")
   283  				continue
   284  			}
   285  			check.exprWithHint(x, kv.Key, utyp.key)
   286  			check.assignment(x, utyp.key, "map literal")
   287  			if x.mode == invalid {
   288  				continue
   289  			}
   290  			if x.mode == constant_ {
   291  				duplicate := false
   292  				xkey := keyVal(x.val)
   293  				if keyIsInterface {
   294  					for _, vtyp := range visited[xkey] {
   295  						if Identical(vtyp, x.typ) {
   296  							duplicate = true
   297  							break
   298  						}
   299  					}
   300  					visited[xkey] = append(visited[xkey], x.typ)
   301  				} else {
   302  					_, duplicate = visited[xkey]
   303  					visited[xkey] = nil
   304  				}
   305  				if duplicate {
   306  					check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
   307  					continue
   308  				}
   309  			}
   310  			check.exprWithHint(x, kv.Value, utyp.elem)
   311  			check.assignment(x, utyp.elem, "map literal")
   312  		}
   313  
   314  	default:
   315  		
   316  		
   317  		for _, e := range e.ElemList {
   318  			if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
   319  				
   320  				
   321  				
   322  				e = kv.Value
   323  			}
   324  			check.use(e)
   325  		}
   326  		
   327  		if isValid(utyp) {
   328  			var qualifier string
   329  			if isElem {
   330  				qualifier = " element"
   331  			}
   332  			var cause string
   333  			if utyp == nil {
   334  				cause = " (no common underlying type)"
   335  			}
   336  			check.errorf(e, InvalidLit, "invalid composite literal%s type %s%s", qualifier, typ, cause)
   337  			x.mode = invalid
   338  			return
   339  		}
   340  	}
   341  
   342  	x.mode = value
   343  	x.typ = typ
   344  }
   345  
   346  
   347  
   348  
   349  
   350  func (check *Checker) indexedElts(elts []syntax.Expr, typ Type, length int64) int64 {
   351  	visited := make(map[int64]bool, len(elts))
   352  	var index, max int64
   353  	for _, e := range elts {
   354  		
   355  		validIndex := false
   356  		eval := e
   357  		if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
   358  			if typ, i := check.index(kv.Key, length); isValid(typ) {
   359  				if i >= 0 {
   360  					index = i
   361  					validIndex = true
   362  				} else {
   363  					check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
   364  				}
   365  			}
   366  			eval = kv.Value
   367  		} else if length >= 0 && index >= length {
   368  			check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
   369  		} else {
   370  			validIndex = true
   371  		}
   372  
   373  		
   374  		if validIndex {
   375  			if visited[index] {
   376  				check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
   377  			}
   378  			visited[index] = true
   379  		}
   380  		index++
   381  		if index > max {
   382  			max = index
   383  		}
   384  
   385  		
   386  		var x operand
   387  		check.exprWithHint(&x, eval, typ)
   388  		check.assignment(&x, typ, "array or slice literal")
   389  	}
   390  	return max
   391  }
   392  
View as plain text