X7ROOT File Manager
Current Path:
/opt/golang/1.19.4/src/cmd/compile/internal/types2
opt
/
golang
/
1.19.4
/
src
/
cmd
/
compile
/
internal
/
types2
/
📁
..
📄
api.go
(17.37 KB)
📄
api_test.go
(79.44 KB)
📄
array.go
(803 B)
📄
assignments.go
(13.89 KB)
📄
basic.go
(1.48 KB)
📄
builtins.go
(23.73 KB)
📄
builtins_test.go
(9.89 KB)
📄
call.go
(19.08 KB)
📄
chan.go
(910 B)
📄
check.go
(17.12 KB)
📄
check_test.go
(8.96 KB)
📄
compilersupport.go
(1.05 KB)
📄
context.go
(4.34 KB)
📄
context_test.go
(2.3 KB)
📄
conversions.go
(8.27 KB)
📄
decl.go
(27.86 KB)
📄
errorcalls_test.go
(1.15 KB)
📄
errors.go
(7.62 KB)
📄
errors_test.go
(1.01 KB)
📄
example_test.go
(7.41 KB)
📄
expr.go
(54.01 KB)
📄
gccgosizes.go
(1017 B)
📄
hilbert_test.go
(3.63 KB)
📄
importer_test.go
(913 B)
📄
index.go
(11.13 KB)
📄
infer.go
(24.86 KB)
📄
initorder.go
(9.55 KB)
📄
instantiate.go
(9.93 KB)
📄
instantiate_test.go
(5.98 KB)
📄
interface.go
(6.04 KB)
📄
issues_test.go
(17.4 KB)
📄
labels.go
(7.05 KB)
📄
lookup.go
(17.01 KB)
📄
main_test.go
(336 B)
📄
map.go
(659 B)
📄
mono.go
(9.03 KB)
📄
mono_test.go
(2.65 KB)
📄
named.go
(22.4 KB)
📄
named_test.go
(2.35 KB)
📄
object.go
(18.8 KB)
📄
object_test.go
(5.13 KB)
📄
objset.go
(928 B)
📄
operand.go
(10.62 KB)
📄
package.go
(2.67 KB)
📄
pointer.go
(635 B)
📄
predicates.go
(14.64 KB)
📄
resolver.go
(24.88 KB)
📄
resolver_test.go
(4.81 KB)
📄
return.go
(4.34 KB)
📄
scope.go
(9.38 KB)
📄
selection.go
(3.99 KB)
📄
self_test.go
(2.58 KB)
📄
signature.go
(12.1 KB)
📄
sizeof_test.go
(1.28 KB)
📄
sizes.go
(7.56 KB)
📄
sizes_test.go
(3.25 KB)
📄
slice.go
(577 B)
📄
stdlib_test.go
(8.8 KB)
📄
stmt.go
(25.66 KB)
📄
struct.go
(6.24 KB)
📄
subst.go
(10.78 KB)
📄
termlist.go
(3.68 KB)
📄
termlist_test.go
(7.18 KB)
📁
testdata
📄
tuple.go
(929 B)
📄
type.go
(2.92 KB)
📄
typelists.go
(1.84 KB)
📄
typeparam.go
(4.75 KB)
📄
typeset.go
(13.87 KB)
📄
typeset_test.go
(2.41 KB)
📄
typestring.go
(10.61 KB)
📄
typestring_test.go
(4.11 KB)
📄
typeterm.go
(3.52 KB)
📄
typeterm_test.go
(5.08 KB)
📄
typexpr.go
(14.8 KB)
📄
unify.go
(18.34 KB)
📄
union.go
(6.1 KB)
📄
universe.go
(7.58 KB)
📄
validtype.go
(7.77 KB)
📄
version.go
(2.13 KB)
Editing: conversions.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 implements typechecking of conversions. package types2 import ( "fmt" "go/constant" "unicode" ) // Conversion type-checks the conversion T(x). // The result is in x. func (check *Checker) conversion(x *operand, T Type) { constArg := x.mode == constant_ constConvertibleTo := func(T Type, val *constant.Value) bool { switch t, _ := under(T).(*Basic); { case t == nil: // nothing to do case representableConst(x.val, check, t, val): return true case isInteger(x.typ) && isString(t): codepoint := unicode.ReplacementChar if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune { codepoint = rune(i) } if val != nil { *val = constant.MakeString(string(codepoint)) } return true } return false } var ok bool var cause string switch { case constArg && isConstType(T): // constant conversion ok = constConvertibleTo(T, &x.val) case constArg && isTypeParam(T): // x is convertible to T if it is convertible // to each specific type in the type set of T. // If T's type set is empty, or if it doesn't // have specific types, constant x cannot be // converted. ok = T.(*TypeParam).underIs(func(u Type) bool { // u is nil if there are no specific type terms if u == nil { cause = check.sprintf("%s does not contain specific types", T) return false } if isString(x.typ) && isBytesOrRunes(u) { return true } if !constConvertibleTo(u, nil) { cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T) return false } return true }) x.mode = value // type parameters are not constants case x.convertibleTo(check, T, &cause): // non-constant conversion ok = true x.mode = value } if !ok { var err error_ if check.conf.CompilerErrorMessages { if cause != "" { // Add colon at end of line if we have a following cause. err.errorf(x, "cannot convert %s to type %s:", x, T) err.errorf(nopos, cause) } else { err.errorf(x, "cannot convert %s to type %s", x, T) } } else { err.errorf(x, "cannot convert %s to %s", x, T) if cause != "" { err.errorf(nopos, cause) } } check.report(&err) x.mode = invalid return } // The conversion argument types are final. For untyped values the // conversion provides the type, per the spec: "A constant may be // given a type explicitly by a constant declaration or conversion,...". if isUntyped(x.typ) { final := T // - For conversions to interfaces, except for untyped nil arguments, // use the argument's default type. // - For conversions of untyped constants to non-constant types, also // use the default type (e.g., []byte("foo") should report string // not []byte as type for the constant "foo"). // - For constant integer to string conversions, keep the argument type. // (See also the TODO below.) if x.typ == Typ[UntypedNil] { // ok } else if isNonTypeParamInterface(T) || constArg && !isConstType(T) { final = Default(x.typ) } else if x.mode == constant_ && isInteger(x.typ) && allString(T) { final = x.typ } check.updateExprType(x.expr, final, true) } x.typ = T } // TODO(gri) convertibleTo checks if T(x) is valid. It assumes that the type // of x is fully known, but that's not the case for say string(1<<s + 1.0): // Here, the type of 1<<s + 1.0 will be UntypedFloat which will lead to the // (correct!) refusal of the conversion. But the reported error is essentially // "cannot convert untyped float value to string", yet the correct error (per // the spec) is that we cannot shift a floating-point value: 1 in 1<<s should // be converted to UntypedFloat because of the addition of 1.0. Fixing this // is tricky because we'd have to run updateExprType on the argument first. // (Issue #21982.) // convertibleTo reports whether T(x) is valid. In the failure case, *cause // may be set to the cause for the failure. // The check parameter may be nil if convertibleTo is invoked through an // exported API call, i.e., when all methods have been type-checked. func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool { // "x is assignable to T" if ok, _ := x.assignableTo(check, T, cause); ok { return true } // "V and T have identical underlying types if tags are ignored // and V and T are not type parameters" V := x.typ Vu := under(V) Tu := under(T) Vp, _ := V.(*TypeParam) Tp, _ := T.(*TypeParam) if IdenticalIgnoreTags(Vu, Tu) && Vp == nil && Tp == nil { return true } // "V and T are unnamed pointer types and their pointer base types // have identical underlying types if tags are ignored // and their pointer base types are not type parameters" if V, ok := V.(*Pointer); ok { if T, ok := T.(*Pointer); ok { if IdenticalIgnoreTags(under(V.base), under(T.base)) && !isTypeParam(V.base) && !isTypeParam(T.base) { return true } } } // "V and T are both integer or floating point types" if isIntegerOrFloat(Vu) && isIntegerOrFloat(Tu) { return true } // "V and T are both complex types" if isComplex(Vu) && isComplex(Tu) { return true } // "V is an integer or a slice of bytes or runes and T is a string type" if (isInteger(Vu) || isBytesOrRunes(Vu)) && isString(Tu) { return true } // "V is a string and T is a slice of bytes or runes" if isString(Vu) && isBytesOrRunes(Tu) { return true } // package unsafe: // "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer" if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(Tu) { return true } // "and vice versa" if isUnsafePointer(Vu) && (isPointer(Tu) || isUintptr(Tu)) { return true } // "V a slice, T is a pointer-to-array type, // and the slice and array types have identical element types." if s, _ := Vu.(*Slice); s != nil { if p, _ := Tu.(*Pointer); p != nil { if a, _ := under(p.Elem()).(*Array); a != nil { if Identical(s.Elem(), a.Elem()) { if check == nil || check.allowVersion(check.pkg, 1, 17) { return true } // check != nil if cause != nil { *cause = "conversion of slices to array pointers requires go1.17 or later" if check.conf.CompilerErrorMessages { *cause += fmt.Sprintf(" (-lang was set to %s; check go.mod)", check.conf.GoVersion) } } return false } } } } // optimization: if we don't have type parameters, we're done if Vp == nil && Tp == nil { return false } errorf := func(format string, args ...interface{}) { if check != nil && cause != nil { msg := check.sprintf(format, args...) if *cause != "" { msg += "\n\t" + *cause } *cause = msg } } // generic cases with specific type terms // (generic operands cannot be constants, so we can ignore x.val) switch { case Vp != nil && Tp != nil: x := *x // don't clobber outer x return Vp.is(func(V *term) bool { if V == nil { return false // no specific types } x.typ = V.typ return Tp.is(func(T *term) bool { if T == nil { return false // no specific types } if !x.convertibleTo(check, T.typ, cause) { errorf("cannot convert %s (in %s) to %s (in %s)", V.typ, Vp, T.typ, Tp) return false } return true }) }) case Vp != nil: x := *x // don't clobber outer x return Vp.is(func(V *term) bool { if V == nil { return false // no specific types } x.typ = V.typ if !x.convertibleTo(check, T, cause) { errorf("cannot convert %s (in %s) to %s", V.typ, Vp, T) return false } return true }) case Tp != nil: return Tp.is(func(T *term) bool { if T == nil { return false // no specific types } if !x.convertibleTo(check, T.typ, cause) { errorf("cannot convert %s to %s (in %s)", x.typ, T.typ, Tp) return false } return true }) } return false } func isUintptr(typ Type) bool { t, _ := under(typ).(*Basic) return t != nil && t.kind == Uintptr } func isUnsafePointer(typ Type) bool { t, _ := under(typ).(*Basic) return t != nil && t.kind == UnsafePointer } func isPointer(typ Type) bool { _, ok := under(typ).(*Pointer) return ok } func isBytesOrRunes(typ Type) bool { if s, _ := under(typ).(*Slice); s != nil { t, _ := under(s.elem).(*Basic) return t != nil && (t.kind == Byte || t.kind == Rune) } return false }
Upload File
Create Folder