...

Source file src/pkg/go/types/conversions.go

     1	// Copyright 2012 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 typechecking of conversions.
     6	
     7	package types
     8	
     9	import "go/constant"
    10	
    11	// Conversion type-checks the conversion T(x).
    12	// The result is in x.
    13	func (check *Checker) conversion(x *operand, T Type) {
    14		constArg := x.mode == constant_
    15	
    16		var ok bool
    17		switch {
    18		case constArg && isConstType(T):
    19			// constant conversion
    20			switch t := T.Underlying().(*Basic); {
    21			case representableConst(x.val, check, t, &x.val):
    22				ok = true
    23			case isInteger(x.typ) && isString(t):
    24				codepoint := int64(-1)
    25				if i, ok := constant.Int64Val(x.val); ok {
    26					codepoint = i
    27				}
    28				// If codepoint < 0 the absolute value is too large (or unknown) for
    29				// conversion. This is the same as converting any other out-of-range
    30				// value - let string(codepoint) do the work.
    31				x.val = constant.MakeString(string(codepoint))
    32				ok = true
    33			}
    34		case x.convertibleTo(check, T):
    35			// non-constant conversion
    36			x.mode = value
    37			ok = true
    38		}
    39	
    40		if !ok {
    41			check.errorf(x.pos(), "cannot convert %s to %s", x, T)
    42			x.mode = invalid
    43			return
    44		}
    45	
    46		// The conversion argument types are final. For untyped values the
    47		// conversion provides the type, per the spec: "A constant may be
    48		// given a type explicitly by a constant declaration or conversion,...".
    49		if isUntyped(x.typ) {
    50			final := T
    51			// - For conversions to interfaces, use the argument's default type.
    52			// - For conversions of untyped constants to non-constant types, also
    53			//   use the default type (e.g., []byte("foo") should report string
    54			//   not []byte as type for the constant "foo").
    55			// - Keep untyped nil for untyped nil arguments.
    56			// - For integer to string conversions, keep the argument type.
    57			//   (See also the TODO below.)
    58			if IsInterface(T) || constArg && !isConstType(T) {
    59				final = Default(x.typ)
    60			} else if isInteger(x.typ) && isString(T) {
    61				final = x.typ
    62			}
    63			check.updateExprType(x.expr, final, true)
    64		}
    65	
    66		x.typ = T
    67	}
    68	
    69	// TODO(gri) convertibleTo checks if T(x) is valid. It assumes that the type
    70	// of x is fully known, but that's not the case for say string(1<<s + 1.0):
    71	// Here, the type of 1<<s + 1.0 will be UntypedFloat which will lead to the
    72	// (correct!) refusal of the conversion. But the reported error is essentially
    73	// "cannot convert untyped float value to string", yet the correct error (per
    74	// the spec) is that we cannot shift a floating-point value: 1 in 1<<s should
    75	// be converted to UntypedFloat because of the addition of 1.0. Fixing this
    76	// is tricky because we'd have to run updateExprType on the argument first.
    77	// (Issue #21982.)
    78	
    79	// convertibleTo reports whether T(x) is valid.
    80	// The check parameter may be nil if convertibleTo is invoked through an
    81	// exported API call, i.e., when all methods have been type-checked.
    82	func (x *operand) convertibleTo(check *Checker, T Type) bool {
    83		// "x is assignable to T"
    84		if x.assignableTo(check, T, nil) {
    85			return true
    86		}
    87	
    88		// "x's type and T have identical underlying types if tags are ignored"
    89		V := x.typ
    90		Vu := V.Underlying()
    91		Tu := T.Underlying()
    92		if IdenticalIgnoreTags(Vu, Tu) {
    93			return true
    94		}
    95	
    96		// "x's type and T are unnamed pointer types and their pointer base types
    97		// have identical underlying types if tags are ignored"
    98		if V, ok := V.(*Pointer); ok {
    99			if T, ok := T.(*Pointer); ok {
   100				if IdenticalIgnoreTags(V.base.Underlying(), T.base.Underlying()) {
   101					return true
   102				}
   103			}
   104		}
   105	
   106		// "x's type and T are both integer or floating point types"
   107		if (isInteger(V) || isFloat(V)) && (isInteger(T) || isFloat(T)) {
   108			return true
   109		}
   110	
   111		// "x's type and T are both complex types"
   112		if isComplex(V) && isComplex(T) {
   113			return true
   114		}
   115	
   116		// "x is an integer or a slice of bytes or runes and T is a string type"
   117		if (isInteger(V) || isBytesOrRunes(Vu)) && isString(T) {
   118			return true
   119		}
   120	
   121		// "x is a string and T is a slice of bytes or runes"
   122		if isString(V) && isBytesOrRunes(Tu) {
   123			return true
   124		}
   125	
   126		// package unsafe:
   127		// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
   128		if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(T) {
   129			return true
   130		}
   131		// "and vice versa"
   132		if isUnsafePointer(V) && (isPointer(Tu) || isUintptr(Tu)) {
   133			return true
   134		}
   135	
   136		return false
   137	}
   138	
   139	func isUintptr(typ Type) bool {
   140		t, ok := typ.Underlying().(*Basic)
   141		return ok && t.kind == Uintptr
   142	}
   143	
   144	func isUnsafePointer(typ Type) bool {
   145		// TODO(gri): Is this (typ.Underlying() instead of just typ) correct?
   146		//            The spec does not say so, but gc claims it is. See also
   147		//            issue 6326.
   148		t, ok := typ.Underlying().(*Basic)
   149		return ok && t.kind == UnsafePointer
   150	}
   151	
   152	func isPointer(typ Type) bool {
   153		_, ok := typ.Underlying().(*Pointer)
   154		return ok
   155	}
   156	
   157	func isBytesOrRunes(typ Type) bool {
   158		if s, ok := typ.(*Slice); ok {
   159			t, ok := s.elem.Underlying().(*Basic)
   160			return ok && (t.kind == Byte || t.kind == Rune)
   161		}
   162		return false
   163	}
   164	

View as plain text