// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
// Source: ../../cmd/compile/internal/types2/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 types

import (
	"go/constant"
	. "internal/types/errors"
	"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)
		// A conversion from an integer constant to an integer type
		// can only fail if there's overflow. Give a concise error.
		// (go.dev/issue/63563)
		if !ok && isInteger(x.typ) && isInteger(T) {
			check.errorf(x, InvalidConversion, "constant %s overflows %s", x.val, T)
			x.mode = invalid
			return
		}
	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 = Unalias(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) {
				if isInteger(x.typ) && isInteger(u) {
					// see comment above on constant conversion
					cause = check.sprintf("constant %s overflows %s (in %s)", x.val, u, T)
				} else {
					cause = check.sprintf("cannot convert %s to type %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 {
		if cause != "" {
			check.errorf(x, InvalidConversion, "cannot convert %s to type %s: %s", x, T, cause)
		} else {
			check.errorf(x, InvalidConversion, "cannot convert %s to type %s", x, T)
		}
		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
		//   and isTypes2, 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").
		// - If !isTypes2, keep untyped nil for untyped nil arguments.
		// - For constant integer to string conversions, keep the argument type.
		//   (See also the TODO below.)
		if isTypes2 && x.typ == Typ[UntypedNil] {
			// ok
		} else if isNonTypeParamInterface(T) || constArg && !isConstType(T) || !isTypes2 && x.isNil() {
			final = Default(x.typ) // default type of untyped nil is untyped nil
		} 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.
// (go.dev/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
	}

	origT := T
	V := Unalias(x.typ)
	T = Unalias(T)
	Vu := under(V)
	Tu := under(T)
	Vp, _ := V.(*TypeParam)
	Tp, _ := T.(*TypeParam)

	// "V and T have identical underlying types if tags are ignored
	// and V and T are not type parameters"
	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 is a slice, T is an array or pointer-to-array type,
	// and the slice and array types have identical element types."
	if s, _ := Vu.(*Slice); s != nil {
		switch a := Tu.(type) {
		case *Array:
			if Identical(s.Elem(), a.Elem()) {
				if check == nil || check.allowVersion(x, go1_20) {
					return true
				}
				// check != nil
				if cause != nil {
					// TODO(gri) consider restructuring versionErrorf so we can use it here and below
					*cause = "conversion of slice to array requires go1.20 or later"
				}
				return false
			}
		case *Pointer:
			if a, _ := under(a.Elem()).(*Array); a != nil {
				if Identical(s.Elem(), a.Elem()) {
					if check == nil || check.allowVersion(x, go1_17) {
						return true
					}
					// check != nil
					if cause != nil {
						*cause = "conversion of slice to array pointer requires go1.17 or later"
					}
					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 ...any) {
		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 type %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 type %s", V.typ, Vp, origT)
				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 type %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
}
