Source file src/internal/types/testdata/spec/conversions.go

     1  // Copyright 2021 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  package conversions
     6  
     7  import "unsafe"
     8  
     9  // constant conversions
    10  
    11  func _[T ~byte]() T { return 255 }
    12  func _[T ~byte]() T { return 256 /* ERRORx `cannot use 256 .* as T value` */ }
    13  
    14  func _[T ~byte]() {
    15  	const _ = T /* ERRORx `T\(0\) .* is not constant` */ (0)
    16  	var _ T = 255
    17  	var _ T = 256 // ERRORx `cannot use 256 .* as T value`
    18  }
    19  
    20  func _[T ~string]() T                { return T('a') }
    21  func _[T ~int | ~string]() T         { return T('a') }
    22  func _[T ~byte | ~int | ~string]() T { return T(256 /* ERRORx `cannot convert 256 .* to type T` */) }
    23  
    24  // implicit conversions never convert to string
    25  func _[T ~string]() {
    26  	var _ string = 0 // ERRORx `cannot use .* as string value`
    27  	var _ T = 0      // ERRORx `cannot use .* as T value`
    28  }
    29  
    30  // failing const conversions of constants to type parameters report a cause
    31  func _[
    32  	T1 any,
    33  	T2 interface{ m() },
    34  	T3 ~int | ~float64 | ~bool,
    35  	T4 ~int | ~string,
    36  ]() {
    37  	_ = T1(0 /* ERRORx `cannot convert 0 .* to type T1: T1 does not contain specific types` */)
    38  	_ = T2(1 /* ERRORx `cannot convert 1 .* to type T2: T2 does not contain specific types` */)
    39  	_ = T3(2 /* ERRORx `cannot convert 2 .* to type T3: cannot convert 2 .* to type bool \(in T3\)` */)
    40  	_ = T4(3.14 /* ERRORx `cannot convert 3.14 .* to type T4: cannot convert 3.14 .* to type int \(in T4\)` */)
    41  }
    42  
    43  // "x is assignable to T"
    44  // - tested via assignability tests
    45  
    46  // "x's type and T have identical underlying types if tags are ignored"
    47  
    48  func _[X ~int, T ~int](x X) T { return T(x) }
    49  func _[X struct {
    50  	f int "foo"
    51  }, T struct {
    52  	f int "bar"
    53  }](x X) T {
    54  	return T(x)
    55  }
    56  
    57  type Foo struct {
    58  	f int "foo"
    59  }
    60  type Bar struct {
    61  	f int "bar"
    62  }
    63  type Far struct{ f float64 }
    64  
    65  func _[X Foo, T Bar](x X) T       { return T(x) }
    66  func _[X Foo | Bar, T Bar](x X) T { return T(x) }
    67  func _[X Foo, T Foo | Bar](x X) T { return T(x) }
    68  func _[X Foo, T Far](x X) T {
    69  	return T(x /* ERROR "cannot convert x (variable of type X constrained by Foo) to type T: cannot convert Foo (in X) to type Far (in T)" */)
    70  }
    71  
    72  // "x's type and T are unnamed pointer types and their pointer base types
    73  // have identical underlying types if tags are ignored"
    74  
    75  func _[X ~*Foo, T ~*Bar](x X) T         { return T(x) }
    76  func _[X ~*Foo | ~*Bar, T ~*Bar](x X) T { return T(x) }
    77  func _[X ~*Foo, T ~*Foo | ~*Bar](x X) T { return T(x) }
    78  func _[X ~*Foo, T ~*Far](x X) T {
    79  	return T(x /* ERROR "cannot convert x (variable of type X constrained by ~*Foo) to type T: cannot convert *Foo (in X) to type *Far (in T)" */)
    80  }
    81  
    82  // Verify that the defined types in constraints are considered for the rule above.
    83  
    84  type (
    85  	B  int
    86  	C  int
    87  	X0 *B
    88  	T0 *C
    89  )
    90  
    91  func _(x X0) T0           { return T0(x /* ERROR "cannot convert" */) } // non-generic reference
    92  func _[X X0, T T0](x X) T { return T(x /* ERROR "cannot convert" */) }
    93  func _[T T0](x X0) T      { return T(x /* ERROR "cannot convert" */) }
    94  func _[X X0](x X) T0      { return T0(x /* ERROR "cannot convert" */) }
    95  
    96  // "x's type and T are both integer or floating point types"
    97  
    98  func _[X Integer, T Integer](x X) T  { return T(x) }
    99  func _[X Unsigned, T Integer](x X) T { return T(x) }
   100  func _[X Float, T Integer](x X) T    { return T(x) }
   101  
   102  func _[X Integer, T Unsigned](x X) T  { return T(x) }
   103  func _[X Unsigned, T Unsigned](x X) T { return T(x) }
   104  func _[X Float, T Unsigned](x X) T    { return T(x) }
   105  
   106  func _[X Integer, T Float](x X) T  { return T(x) }
   107  func _[X Unsigned, T Float](x X) T { return T(x) }
   108  func _[X Float, T Float](x X) T    { return T(x) }
   109  
   110  func _[X, T Integer | Unsigned | Float](x X) T { return T(x) }
   111  func _[X, T Integer | ~string](x X) T {
   112  	return T(x /* ERROR "cannot convert x (variable of type X constrained by Integer | ~string) to type T: cannot convert string (in X) to type int (in T)" */)
   113  }
   114  
   115  // "x's type and T are both complex types"
   116  
   117  func _[X, T Complex](x X) T { return T(x) }
   118  func _[X, T Float | Complex](x X) T {
   119  	return T(x /* ERROR "cannot convert x (variable of type X constrained by Float | Complex) to type T: cannot convert float32 (in X) to type complex64 (in T)" */)
   120  }
   121  
   122  // "x is an integer or a slice of bytes or runes and T is a string type"
   123  
   124  type myInt int
   125  type myString string
   126  
   127  func _[T ~string](x int) T      { return T(x) }
   128  func _[T ~string](x myInt) T    { return T(x) }
   129  func _[X Integer](x X) string   { return string(x) }
   130  func _[X Integer](x X) myString { return myString(x) }
   131  func _[X Integer](x X) *string {
   132  	return (*string)(x /* ERROR "cannot convert x (variable of type X constrained by Integer) to type *string: cannot convert int (in X) to type *string" */)
   133  }
   134  
   135  func _[T ~string](x []byte) T                           { return T(x) }
   136  func _[T ~string](x []rune) T                           { return T(x) }
   137  func _[X ~[]byte, T ~string](x X) T                     { return T(x) }
   138  func _[X ~[]rune, T ~string](x X) T                     { return T(x) }
   139  func _[X Integer | ~[]byte | ~[]rune, T ~string](x X) T { return T(x) }
   140  func _[X Integer | ~[]byte | ~[]rune, T ~*string](x X) T {
   141  	return T(x /* ERROR "cannot convert x (variable of type X constrained by Integer | ~[]byte | ~[]rune) to type T: cannot convert int (in X) to type *string (in T)" */)
   142  }
   143  
   144  // "x is a string and T is a slice of bytes or runes"
   145  
   146  func _[T ~[]byte](x string) T { return T(x) }
   147  func _[T ~[]rune](x string) T { return T(x) }
   148  func _[T ~[]rune](x *string) T {
   149  	return T(x /* ERROR "cannot convert x (variable of type *string) to type T: cannot convert *string to type []rune (in T)" */)
   150  }
   151  
   152  func _[X ~string, T ~[]byte](x X) T           { return T(x) }
   153  func _[X ~string, T ~[]rune](x X) T           { return T(x) }
   154  func _[X ~string, T ~[]byte | ~[]rune](x X) T { return T(x) }
   155  func _[X ~*string, T ~[]byte | ~[]rune](x X) T {
   156  	return T(x /* ERROR "cannot convert x (variable of type X constrained by ~*string) to type T: cannot convert *string (in X) to type []byte (in T)" */)
   157  }
   158  
   159  // package unsafe:
   160  // "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
   161  
   162  type myUintptr uintptr
   163  
   164  func _[X ~uintptr](x X) unsafe.Pointer  { return unsafe.Pointer(x) }
   165  func _[T unsafe.Pointer](x myUintptr) T { return T(x) }
   166  func _[T unsafe.Pointer](x int64) T {
   167  	return T(x /* ERROR "cannot convert x (variable of type int64) to type T: cannot convert int64 to type unsafe.Pointer (in T)" */)
   168  }
   169  
   170  // "and vice versa"
   171  
   172  func _[T ~uintptr](x unsafe.Pointer) T  { return T(x) }
   173  func _[X unsafe.Pointer](x X) uintptr   { return uintptr(x) }
   174  func _[X unsafe.Pointer](x X) myUintptr { return myUintptr(x) }
   175  func _[X unsafe.Pointer](x X) int64 {
   176  	return int64(x /* ERROR "cannot convert x (variable of type X constrained by unsafe.Pointer) to type int64: cannot convert unsafe.Pointer (in X) to type int64" */)
   177  }
   178  
   179  // "x is a slice, T is an array or pointer-to-array type,
   180  // and the slice and array types have identical element types."
   181  
   182  func _[X ~[]E, T ~[10]E, E any](x X) T  { return T(x) }
   183  func _[X ~[]E, T ~*[10]E, E any](x X) T { return T(x) }
   184  
   185  // ----------------------------------------------------------------------------
   186  // The following declarations can be replaced by the exported types of the
   187  // constraints package once all builders support importing interfaces with
   188  // type constraints.
   189  
   190  type Signed interface {
   191  	~int | ~int8 | ~int16 | ~int32 | ~int64
   192  }
   193  
   194  type Unsigned interface {
   195  	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
   196  }
   197  
   198  type Integer interface {
   199  	Signed | Unsigned
   200  }
   201  
   202  type Float interface {
   203  	~float32 | ~float64
   204  }
   205  
   206  type Complex interface {
   207  	~complex64 | ~complex128
   208  }
   209  

View as plain text