// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.// Source: ../../cmd/compile/internal/types2/operand.go// Copyright 2012 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// This file defines operands and associated operations.package typesimport (.)// An operandMode specifies the (addressing) mode of an operand.type operandMode byteconst ( invalid operandMode = iota// operand is invalid novalue // operand represents no value (result of a function call w/o result) builtin // operand is a built-in function typexpr // operand is a type constant_ // operand is a constant; the operand's typ is a Basic type variable // operand is an addressable variable mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment) value // operand is a computed value nilvalue // operand is the nil value - only used by types2 commaok // like value, but operand may be used in a comma,ok expression commaerr // like commaok, but second value is error, not boolean cgofunc // operand is a cgo function)var operandModeString = [...]string{invalid: "invalid operand",novalue: "no value",builtin: "built-in",typexpr: "type",constant_: "constant",variable: "variable",mapindex: "map index expression",value: "value",nilvalue: "nil", // only used by types2commaok: "comma, ok expression",commaerr: "comma, error expression",cgofunc: "cgo function",}// An operand represents an intermediate value during type checking.// Operands have an (addressing) mode, the expression evaluating to// the operand, the operand's type, a value for constants, and an id// for built-in functions.// The zero value of operand is a ready to use invalid operand.type operand struct { mode operandMode expr ast.Expr typ Type val constant.Value id builtinId}// Pos returns the position of the expression corresponding to x.// If x is invalid the position is nopos.func ( *operand) () token.Pos {// x.expr may not be set if x is invalidif .expr == nil {returnnopos }return .expr.Pos()}// Operand string formats// (not all "untyped" cases can appear due to the type system,// but they fall out naturally here)//// mode format//// invalid <expr> ( <mode> )// novalue <expr> ( <mode> )// builtin <expr> ( <mode> )// typexpr <expr> ( <mode> )//// constant <expr> (<untyped kind> <mode> )// constant <expr> ( <mode> of type <typ>)// constant <expr> (<untyped kind> <mode> <val> )// constant <expr> ( <mode> <val> of type <typ>)//// variable <expr> (<untyped kind> <mode> )// variable <expr> ( <mode> of type <typ>)//// mapindex <expr> (<untyped kind> <mode> )// mapindex <expr> ( <mode> of type <typ>)//// value <expr> (<untyped kind> <mode> )// value <expr> ( <mode> of type <typ>)//// nilvalue untyped nil// nilvalue nil ( of type <typ>)//// commaok <expr> (<untyped kind> <mode> )// commaok <expr> ( <mode> of type <typ>)//// commaerr <expr> (<untyped kind> <mode> )// commaerr <expr> ( <mode> of type <typ>)//// cgofunc <expr> (<untyped kind> <mode> )// cgofunc <expr> ( <mode> of type <typ>)func operandString( *operand, Qualifier) string {// special-case nilifisTypes2 {if .mode == nilvalue {switch .typ {casenil, Typ[Invalid]:return"nil (with invalid type)"caseTyp[UntypedNil]:return"nil"default:returnfmt.Sprintf("nil (of type %s)", TypeString(.typ, )) } } } else { // go/typesif .mode == value && .typ == Typ[UntypedNil] {return"nil" } }varbytes.Buffervarstringif .expr != nil { = ExprString(.expr) } else {switch .mode {casebuiltin: = predeclaredFuncs[.id].namecasetypexpr: = TypeString(.typ, )caseconstant_: = .val.String() } }// <expr> (if != "" { .WriteString() .WriteString(" (") }// <untyped kind> := falseswitch .mode {caseinvalid, novalue, builtin, typexpr:// no typedefault:// should have a type, but be cautious (don't crash during printing)if .typ != nil {ifisUntyped(.typ) { .WriteString(.typ.(*Basic).name) .WriteByte(' ')break } = true } }// <mode> .WriteString(operandModeString[.mode])// <val>if .mode == constant_ {if := .val.String(); != { .WriteByte(' ') .WriteString() } }// <typ>if {ifisValid(.typ) {varstringifisGeneric(.typ) { = " of generic type " } else { = " of type " } .WriteString()WriteType(&, .typ, )if , := Unalias(.typ).(*TypeParam); != nil { .WriteString(" constrained by ")WriteType(&, .bound, ) // do not compute interface type sets here// If we have the type set and it's empty, say so for better error messages.ifhasEmptyTypeset() { .WriteString(" with empty type set") } } } else { .WriteString(" with invalid type") } }// )if != "" { .WriteByte(')') }return .String()}func ( *operand) () string {returnoperandString(, nil)}// setConst sets x to the untyped constant for literal lit.func ( *operand) ( token.Token, string) {varBasicKindswitch {casetoken.INT: = UntypedIntcasetoken.FLOAT: = UntypedFloatcasetoken.IMAG: = UntypedComplexcasetoken.CHAR: = UntypedRunecasetoken.STRING: = UntypedStringdefault:panic("unreachable") } := makeFromLiteral(, )if .Kind() == constant.Unknown { .mode = invalid .typ = Typ[Invalid]return } .mode = constant_ .typ = Typ[] .val = }// isNil reports whether x is the (untyped) nil value.func ( *operand) () bool {ifisTypes2 {return .mode == nilvalue } else { // go/typesreturn .mode == value && .typ == Typ[UntypedNil] }}// assignableTo reports whether x is assignable to a variable of type T. If the// result is false and a non-nil cause is provided, it may be set to a more// detailed explanation of the failure (result != ""). The returned error code// is only valid if the (first) result is false. The check parameter may be nil// if assignableTo is invoked through an exported API call, i.e., when all// methods have been type-checked.func ( *operand) ( *Checker, Type, *string) (bool, Code) {if .mode == invalid || !isValid() {returntrue, 0// avoid spurious errors } := := Unalias(.typ) = Unalias()// x's type is identical to TifIdentical(, ) {returntrue, 0 } := under() := under() , := .(*TypeParam) , := .(*TypeParam)// x is an untyped value representable by a value of type T.ifisUntyped() {assert( == nil)if != nil {// T is a type parameter: x is assignable to T if it is // representable by each specific type in the type set of T.return .is(func( *term) bool {if == nil {returnfalse }// A term may be a tilde term but the underlying // type of an untyped value doesn't change so we // don't need to do anything special. , , := .implicitTypeAndValue(, .typ)return != nil }), IncompatibleAssign } , , := .implicitTypeAndValue(, )return != nil, IncompatibleAssign }// Vu is typed// x's type V and T have identical underlying types // and at least one of V or T is not a named type // and neither V nor T is a type parameter.ifIdentical(, ) && (!hasName() || !hasName()) && == nil && == nil {returntrue, 0 }// T is an interface type, but not a type parameter, and V implements T. // Also handle the case where T is a pointer to an interface so that we get // the Checker.implements error cause.if , := .(*Interface); && == nil || isInterfacePtr() {if .implements(.Pos(), , , false, ) {returntrue, 0 }// V doesn't implement T but V may still be assignable to T if V // is a type parameter; do not report an error in that case yet.if == nil {returnfalse, InvalidIfaceAssign }if != nil { * = "" } }// If V is an interface, check if a missing type assertion is the problem.if , := .(*Interface); != nil && == nil {if .implements(.Pos(), , , false, nil) {// T implements V, so give hint about type assertion.if != nil { * = "need type assertion" }returnfalse, IncompatibleAssign } }// x is a bidirectional channel value, T is a channel // type, x's type V and T have identical element types, // and at least one of V or T is not a named type.if , := .(*Chan); && .dir == SendRecv {if , := .(*Chan); && Identical(.elem, .elem) {return !hasName() || !hasName(), InvalidChanAssign } }// optimization: if we don't have type parameters, we're doneif == nil && == nil {returnfalse, IncompatibleAssign } := func( string, ...any) {if != nil && != nil { := .sprintf(, ...)if * != "" { += "\n\t" + * } * = } }// x's type V is not a named type and T is a type parameter, and // x is assignable to each specific type in T's type set.if !hasName() && != nil { := false := IncompatibleAssign .is(func( *term) bool {if == nil {returnfalse// no specific types } , = .(, .typ, )if ! { ("cannot assign %s to %s (in %s)", .typ, .typ, )returnfalse }returntrue })return , }// x's type V is a type parameter and T is not a named type, // and values x' of each specific type in V's type set are // assignable to T.if != nil && !hasName() { := * // don't clobber outer x := false := IncompatibleAssign .is(func( *term) bool {if == nil {returnfalse// no specific types } .typ = .typ , = .(, , )if ! { ("cannot assign %s (in %s) to %s", .typ, , )returnfalse }returntrue })return , }returnfalse, IncompatibleAssign}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.